首先,让我们使用变量x
的get和set方法来考虑这个工作示例class Foo:
def __init__(self):
self._x = 0
def set_x(self, x):
self._x = x
def get_x(self):
return self._x
class Bar:
def __init__(self, set_method):
self._set_method = set_method
def set_x(self, x):
self._set_method(x)
f = Foo()
f.set_x(5)
print(f.get_x())
# Prints 5
b = Bar(f.set_x)
b.set_x(10)
print(f.get_x())
# Prints 10
正如您所看到的,我将可能的类Foo的实例f的变量x设置为类Bar的实例b。
现在,我想做同样的事情,但是使用属性装饰器,大致就像这样
class Foo:
def __init__(self):
self._x = 0
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x
class Bar:
def __init__(self, x_property):
self._x_property = x_property
def set_x(self, x):
self.x_property = x
f = Foo()
f.x = 5
print(f.x)
# Prints 5
b = Bar(f.x)
b.set_x(10)
print(f.x)
# Prints 5
会发生的是,值5而不是属性被传递给实例b,这意味着b不能访问实例f中的x。有没有一个很好的方法来解决这个问题?
我还想为get方法做同样的事情。在第一个需要我传递两个方法的代码中,但如果有办法让第二个代码工作,我希望只需要传递属性,然后我可以设置并获取作为普通变量。
我真的想要使用属性装饰器或类似的东西,因为它会清理我的代码很多。我使用python 3.5.2。
谢谢, 安德烈亚斯
答案 0 :(得分:0)
您可以通过访问fset
的{{1}}属性来完成此操作。注意使用类点表示法而不是实例点。 Foo.x
接受两个参数:要访问的实例和要写入的值。这是一个有效的例子
fset
请注意,我们必须将class Foo:
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x
class Bar:
def __init__(self, x_property):
self.x_property = x_property
def set_x(self, foo, value):
self.x_property(foo, value)
f = Foo()
f.x = 5
print(f.x)
b = Bar(Foo.x.fset)
b.set_x(f, 10)
print(f.x)
传递给f
,因为我们需要它来调用设置器。您可以通过使用set_x
模块中的f
将partial
绑定到属性设置器来消除functools
参数。将f
绑定传递到partial
的构造函数中。
Bar
重新命名class Bar:
def __init__(self, x_property):
self.x_property = x_property
def set_x(self, value):
self.x_property(value)
f = Foo()
b = Bar(partial(Foo.x.fset, f))
b.set_x(10)
print(f.x)
可能是明智的选择。就x_property
而言,它实际上只是一个函数。不必是属性。