当 __getattribute__ 和 __getattr__ 存在时,为什么 Python 类实例中会出现“流氓”形状属性?

问题描述

我试图了解 dunder getattributegetattr 方法功能。在试验时,我注意到我的班级中出现了一个意想不到的形状属性。我找不到任何解释为什么会发生这种情况。

class X:
    def __init__(self,count):
        self.count = count

x = X(42)

导致 x 在 PyCharm 调试模式下显示为:

x = {X}
  count = {int}42

class X:
    def __init__(self,count):
        self.count = count

    def __getattribute__(self,item):
        # Calling the super class to avoid recursion
        return super(X,self).__getattribute__(item)

    def __getattr__(self,item):
        return self.__setattr__(item,'fred')

x = X(42)

导致 x 在 PyCharm 调试模式下显示为:

x = {X}
  count = {int}42
  shape = {str} 'fred'

属性“形状”从何而来,其目的是什么?

解决方法

简单的答案是shape 创建 shape 属性,如果有人试图访问它。由于 xX 上都没有现有的 x.shape 属性,因此通过调用 x.__getattr__('shape') 来解析 shape

我无法解释谁(PyCharm 本身?)试图访问 {{1}} 或他们为什么会这样做。