【问题标题】:How to pass property methods as arugments in Python如何在 Python 中将属性方法作为参数传递
【发布时间】:2017-07-29 06:48:01
【问题描述】:

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

谢谢, 安德烈亚斯

【问题讨论】:

  • 总体而言,您想要完成什么?

标签: python-3.x methods properties


【解决方案1】:

您可以通过访问Foo.x 的fset 属性来完成此操作。请注意使用类点表示法而不是实例点表示法。 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,因为我们需要它来调用setter。您可以通过使用partial 模块中的partial 将f 绑定到属性设置器来消除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 和这一点可能是明智的。就Bar 而言,它实际上只是一个功能。它不一定是属性。

【讨论】:

    猜你喜欢
    • 2010-10-16
    • 1970-01-01
    • 2010-11-13
    • 2021-02-05
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多