如何在Python中将属性方法作为arugments传递

时间:2017-03-08 15:46:04

标签: python-3.x methods properties

首先,让我们使用变量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。

谢谢, 安德烈亚斯

1 个答案:

答案 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模块中的fpartial绑定到属性设置器来消除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而言,它实际上只是一个函数。不必是属性。