同名属性的2个名称

时间:2015-06-03 21:05:03

标签: python

我想知道是否有办法联系"一个类的两个属性或者为同一个属性赋予两个名称?

例如,我实际上正在编写一个脚本,该脚本根据用户提供的数据创建三角形。我的三角形是ABC。这个三角形的边是AB,BC和CA.所以三角形有这3个属性(self.AB,self.BC,self.CA)。但AB = BA,所以我希望允许用户print myInstance.BA代替print myInstance.AB

所以我想创建属性self.AB和属性BA(返回self.AB)。当我尝试print myInstance.BA代替print myInstance.AB而我贪婪时,这工作正常......

我还希望允许用户执行myInstance.BA = 5而不是myInstance.AB = 5,并且在执行此操作时也会编辑属性AB。

有没有办法做到这一点?

2 个答案:

答案 0 :(得分:11)

Python属性可以有setter。所以你需要的只是

class Foo(object):

  @property
  def BA(self):
      return self.AB

  @BA.setter
  def BA(self, value):
      self.AB = value

在@ amccormack的回答中,如果你可以依赖属性名称的顺序,这对于例如edge bc,cd:

  class Foo(object):


      def __init__(self):
          self.ab = 100

      def __getattr__(self, name):
          return getattr(self, "".join(sorted(name)))

      def __setattr__(self, name, value):
          super(Foo, self).__setattr__("".join(sorted(name)), value)


  f = Foo()

  print f.ba
  f.ba = 200
  print f.ba

答案 1 :(得分:3)

执行此操作的一种方法是将您的边存储在字典的自定义实现中,如this SO answer中所述。

这种技术的好处是,您在编写代码时无需知道边的名称。

我们所做的是更改哈希查找功能,以便在字典查找密钥之前,它会对密钥进行排序。因为键是排序的,所以ba变为ab等。排序发生在__keytransform__类中的SideDict函数中。

import collections


class TransformedDict(collections.MutableMapping):
    """A dictionary that applies an arbitrary key-altering
       function before accessing the keys"""

    def __init__(self, *args, **kwargs):
        self.store = dict()
        self.update(dict(*args, **kwargs))  # use the free update to set keys

    def __getitem__(self, key):
        return self.store[self.__keytransform__(key)]

    def __setitem__(self, key, value):
        self.store[self.__keytransform__(key)] = value

    def __delitem__(self, key):
        del self.store[self.__keytransform__(key)]

    def __iter__(self):
        return iter(self.store)

    def __len__(self):
        return len(self.store)

    def __keytransform__(self, key):
        return key

class SideDict(TransformedDict):

    def __keytransform__(self, key):
        return ''.join(sorted(key))

side=SideDict()
print 'assign 3 to abc'
side['abc']=3
print "side['abc']", side['abc']
print 'assign 5 to abc'
side['bac']=5
print "side['abc']", side['abc']
print "side['bca']", side['bca']

运行此代码会产生:

assign 3 to abc
side['abc'] 3
assign 5 to abc
side['abc'] 5
side['bca'] 5