2 names for a same attribute
我想知道是否有一种方法可以"链接"一个类的两个属性,或者将两个名称赋予同一个属性?
例如,我正在编写一个脚本,它根据用户提供的数据创建三角形。我的三角形是ABC。三角形的边是ab、bc和ca。因此三角形有三个属性(self.ab、self.bc、self.ca)。但是ab=ba,所以我想允许用户使用
所以我想创建属性self.ab和属性ba(返回self.ab)。当我试着用
我还希望允许用户使用
有办法吗?
python属性可以有setter。所以你只需要
1 2 3 4 5 6 7 8 9 | class Foo(object): @property def BA(self): return self.AB @BA.setter def BA(self, value): self.AB = value |
并由@amccormack的答案inspred,如果您可以依赖属性名的顺序,则这更一般地适用于边缘BC、CD:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
实现这一点的一种方法是将您的边存储在字典的自定义实现中,如本so答案中所述。
这种技术的好处是,在编写代码时,您不必知道边的名称是什么。
我们所做的是更改哈希查找函数,以便在字典查找键之前,对键进行排序。因为键被排序,所以ba变为ab等。排序发生在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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'] |
运行此代码会产生:
1 2 3 4 5 | assign 3 to abc side['abc'] 3 assign 5 to abc side['abc'] 5 side['bca'] 5 |