python - 如何在 magic __getattr__ 中获取实例属性?

标签 python python-3.x getattr

在一个类中,我想将对 inst.addr 的调用映射到通过调用 inst.addr_fun() 创建的值,因此创建了以下代码:

class Common:
    ...
    def __getattr__(self, name):
        if hasattr(self, '{}_fun'.format(name)):
            return getattr(self, '{}_fun'.format(name))()
        else:  
            raise AttributeError('attribute unknown in instance')
    def addr_fun(self):
        return 42

但是,它会导致递归,因为 getattr 调用 __getattr__,所以我无法访问 addr_fun 函数。

如何访问实例中的命名属性?

最佳答案

Python language refererence about __getattr__ :

object.__getattr__(self, name)

Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self). name is the attribute name. This method should return the (computed) attribute value or raise an AttributeError exception.

Note that if the attribute is found through the normal mechanism, __getattr__() is not called. (This is an intentional asymmetry between __getattr__() and __setattr__().) This is done both for efficiency reasons and because otherwise __getattr__() would have no way to access other attributes of the instance. Note that at least for instance variables, you can fake total control by not inserting any values in the instance attribute dictionary (but instead inserting them in another object). See the __getattribute__() method below for a way to actually get total control over attribute access.

这意味着 __getattr__ 只有在找不到实例变量、类属性和同名方法时才会被调用。

因此您的代码适用于“addr”。您将获得其他名称的无限递归,因为 hasattr() also uses __getattr__ .

您应该避免在 __getattr__ 中使用 hasattr()getattr()。 相反,您可以在捕获 AttributeErrortry-except block 中使用 super().__getattribute__(name)

请注意 super().__getattribute__(name) 不会在父类上调用 __getattr__(name)。因此,如果您想要支持一个类层次结构,其中 __getattr__ 可能链接到另一个类的 __getattr__ 方法,您需要调用 super().__getattr__(name) 如果 super.__getattribute__() 失败。

关于python - 如何在 magic __getattr__ 中获取实例属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42065239/

相关文章:

python - 词典不添加新词条

python - 如何正确删除 Scikit-Learn 的 DPGMM 的冗余组件?

python - 如何将 pandas 数据帧切片作为函数中的参数?

Python,Django,如何使用getattr(或其他方法)调用具有多个属性的对象?

python - 如何使用getattr调用字符串作为属性?

python - 延迟中未处理的错误?将 UNIX 套接字与 Twisted 一起使用

python - 计算日期之前的值,迭代每一行

python - Sounddevice ValueError : could not broadcast input array from shape (2048) into shape (2048, 1)

python - 如何用Python造一个句子?

python - 如何使用 tkinter 提示用户将 DataFrame 保存到 Excel 文件?