我有一个具有属性的类,这些属性引用了该类的另一个属性。请参阅Device
,value1
和value2
,其中包含对interface
的引用:
class Interface(object):
def __init__(self):
self.port=None
class Value(object):
def __init__(self, interface, name):
self.interface=interface
self.name=name
def get(self):
return "Getting Value \"%s\" with interface \"%s\""%(self.name, self.interface.port)
class Device(object):
interface=Interface()
value1=Value(interface, name="value1")
value2=Value(interface, name="value2")
def __init__(self, port):
self.interface.port=port
if __name__=="__main__":
d1=Device("Foo")
print d1.value1.get() # >>> Getting Value "value1" with interface "Foo"
d2=Device("Bar")
print d2.value1.get() # >>> Getting Value "value1" with interface "Bar"
print d1.value1.get() # >>> Getting Value "value1" with interface "Bar"
最后一次打印错误,因为d1
应该有“Foo”界面。我知道什么是错的:当解析类定义(一次)时,执行行interface=Interface()
行。因此,每个Device
类都具有相同的interface
实例。
我可以将Device
类更改为:
class Device(object):
interface=Interface()
value1=Value(interface, name="value1")
value2=Value(interface, name="value2")
def __init__(self, port):
self.interface=Interface()
self.interface.port=port
所以这也行不通:值仍然有对原始接口实例的引用,而self.interface只是另一个实例......
现在的输出是:
>>> Getting Value "value1" with interface "None"
>>> Getting Value "value1" with interface "None"
>>> Getting Value "value1" with interface "None"
那我怎么能用pythonic方式解决这个问题呢?我可以在Device
类中设置一个函数来查找类型为Value
的属性,并将它们重新分配给新接口。对于典型的解决方案,这不是常见问题吗?
谢谢!
答案 0 :(得分:4)
interface
是类属性。所以当你这样做时
d2=Device("Bar")
您正在更改类interface
的所有对象的Device
的端口。
如果要为每个对象实例提供这些属性,则必须将它们放入__init__
方法中:
class Device(object):
def __init__(self, port):
self.interface=Interface()
self.value1=Value(self.interface, name="value1")
self.value2=Value(self.interface, name="value2")
self.interface.port=port
如果你真的想与所有对象共享一个值,你应该只使用类属性。
除此之外,我不知道你在这里想要完成什么。为什么首先将它定义为类属性?
答案 1 :(得分:2)
除非您的值是Device的方法,否则不能推迟接口查找。也许这样的事情可以做你想要的吗?
def value(name):
def get(self):
print 'Getting %s from port %s' % (name, self.interface.port)
def set(self, v):
print 'Setting %s to %s on port %s' % (name, v, self.interface.port)
return property(get, set)
class Device(object):
value1 = value('value1')
value2 = value('value2')
def __init__(self, interface):
self.interface = interface
class Interface(object):
def __init__(self, port):
self.port = port
d = Device(Interface(1234))
d.value1
d.value2 = 42
如果你希望你的价值观不仅仅是获取和设定,那就更难了。