Python:重载 __getattr__ 和属性,使 __setattr__ 正常工作

标签 python properties

考虑以下 python 代码:

class Foo(object):

    def __init__(self, value):
        self._value = value

    @property
    def value(self):
        return "value: {v}".format(v=self._value)

    @value.setter
    def value(self, value):
        self._value = value

class Bar(object):

    def __init__(self):
        self.foo = Foo('foo')

    def __getattr__(self, attr, *args, **kwargs):
        """
        Intercepts attribute calls, and if we don't have it, look at the
        webelement to see if it has the attribute.
        """

        # Check first to see if it looks like a method, if not then just return
        # the attribute the way it is.
        # Note: this has only been tested with variables, and methods.
        if not hasattr(getattr(self.foo, attr), '__call__'):
            return getattr(self.foo, attr)

        def callable(*args, **kwargs):
            '''
            Returns the method from the webelement module if found
            '''
            return getattr(self.foo, attr)(*args, **kwargs)
        return callable

>>> b = Bar()
>>> b.foo
<__main__.Foo object at 0x819410>
>>> b.foo.value
'value: foo'
>>> b.foo.value = '2'
>>> b.foo.value
'value: 2'
>>> b.value
'value: 2'
>>> b.value = '3'
>>> b.value
'3'

最后一部分,我希望它是“值:3”而不是“3”,因为现在我的属性“值”现在是一个属性。

是否可能,如果可能,我会怎么做。

最佳答案

你的 __getattr__返回属性,而不是属性本身。当您访问 getattr(self.foo, attr)它相当于 self.foo.value并返回它,并在那时调用该属性。

因此你需要实现一个 __setattr__方法也是,镜像__getattr__并将值设置传递给包含的 foo对象。

在幕后,Python 将属性实现为 descriptors ;他们的 __get__() method被下级调用 __getattribute__ method ,这会导致它们返回它们的计算值。返回的永远不是属性对象本身。

这是一个例子 __setattr__ :

def __setattr__(self, attr, value):
    if hasattr(self, 'foo') and hasattr(self.foo, attr):
        setattr(self.foo, attr, value)
        return
    super(Bar, self).__setattr__(attr, value)

注意:因为您的 __init__self.foo ,你需要测试是否 foo存在于您的类(class) ( hasattr(self, 'foo') 。您还需要调用原始 __setattr__ 实现以确保像 self.foo = Foo() 这样的事情仍然有效。

关于Python:重载 __getattr__ 和属性,使 __setattr__ 正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12489723/

相关文章:

Python3 在 tar 文件中处理 csv 文件

ios - 使用全局变量和常量是一种好习惯吗? ( swift 5)

java - 无法加载 Hibernate.cfg.xml 的属性文件

python - 使用 imaplib 库连接到电子邮件时遇到 AUTHENTICATIONFAILED 错误

Python - 动态嵌套列表

python - Pandas :设置编号。最大行数

python - 在 PyQt 中将变量从一个类传递到另一个类

c# - 自上次访问属性以来耗时

java - 当属性在属性文件中重复时引发异常

java - spring 应用程序如何在 war 之外保留属性文件