python - 'super' 对象在 python3 中没有属性 '__getattr__'

标签 python python-3.x python-3.4

如何用 python 3 和继承覆盖 __getattr__

当我使用以下内容时:

class MixinA:
    def __getattr__(self, item):
       # Process item and return value if known
       if item == 'a':
           return 'MixinA'

       # If it is unknown, pass it along to give 
       # a chance to another class to handle it
       return super().__getattr__(item)

class MixinB:
    def __getattr__(self, item):
       # Process item and return value if known
       if item == 'b':
           return 'MixinB'

       # If it is unknown, pass it along to give 
       # a chance to another class to handle it
       return super().__getattr__(item)

class Example(MixinA, MixinB):
    # main class
    pass

我收到这个错误。

>>> e  = Example()
>>> e.a
'MixinA'
>>> e.b
'MixinB'
>>> e.c
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
...
AttributeError: 'super' object has no attribute '__getattr__'  

难道我不能得到引用原始类和属性的属性错误吗?也就是说:

AttributeError: 'Example' object has no attribute 'c'

PS:我找到了这篇文章'super' object not calling __getattr__但我不确定是否有解决方案。

最佳答案

Python 属性检索机制的工作方式是类 __getattr__被称为“最后资源”以尝试获取该类实例的属性。

您的代码是正确的 - 由于您的“示例”父类(super class) - 在本例中为“对象” - 没有 __getattr__ 而失败属性。 如果您不在深层类层次结构中并且想要为直接从对象继承的类执行自定义属性检索(在 Py3 中可以表示为完全没有基数,就像您的代码中的情况一样) - 只需引发“AttributeError”如果您的自定义查找失败。

相反,如果您的意图是让您的自定义搜索优先于 Python 的正常属性检索机制(并且不被称为后备),您应该实现 __getattribute__而不是 __getattr__ .

在这种情况下,基类 - 对象 - 确实有一个 __getattribute__您必须为普通属性检索调用的方法 - 问题是您必须为您想要的一切调用它 - 包括方法名称和您设置的已知属性。即:一些东西:

class Example:

    def __init__(self):
       self.attrs_to_override = ["attr1", "foo", "bar"]

    def docustomstuff(self, attr):
        ...

    def __getattribute__(self, attr):
       getter = super().__getattribute__
       if attr in getter("attrs_to_override"):
            getter("docustomstuff")(attr)
       return getter(attr)

简而言之,如果你认为你应该实现__getattribute__而不是 __getattr__您可能正在尝试错误的方法,除非在非常特殊的情况下。到目前为止您可能不知道的是:__getattr__如果所需名称的普通属性尚不存在,则不会调用它,因此无需在父类(super class)中调用它(除非父类(super class)万一不是对象并且具有已知的定制)

编辑

或者,只需检查下一个父类(super class)是否有 __getattr__以最简单的方式:

...
if hasattr(super(), "__getattr__"):
    return super().__getattr__(attr)
raise AttributeError

关于python - 'super' 对象在 python3 中没有属性 '__getattr__',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28861064/

相关文章:

python - timeit 返回什么时间单位?

python - 从 Beautifulsoup 的标签 "extract"中提取内容

python - 从 python 子进程模块启动模块 shell 命令

python - 为什么推荐使用 PyPI 使用 API token ?

python - 导入错误 : cannot import name 'PandasError'

python - "InteractiveShell.ast_node_interactivity"- Jupyter notebook 给出的数据太多

Python 3 - 通过循环重建给定集合来减少列表

Python:返回列表不起作用

python - Numpy 矩阵维数-tfidf 向量

python - Python 中的函数定义和调用