我想知道是否有办法联系"一个类的两个属性或者为同一个属性赋予两个名称?
例如,我实际上正在编写一个脚本,该脚本根据用户提供的数据创建三角形。我的三角形是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。
有没有办法做到这一点?
答案 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