X.__getitem__(1) vs 类型(X).__getitem__(X, 1)
X.__getitem__(1) vs type(X).__getitem__(X, 1)
class C:
data = 'spam'
def __getattr__(self, name):
print('getattr:', name)
return getattr(self.data, name)
X = C()
X.__getitem__(1) // <-- works!
type(X).__getitem__(X, 1) // <-- AttributeError: type object 'C' has no attribute '__getitem__'
既然type(X).__getitem__(X, 1)
在class C中找不到__getitem__
方法,难道不应该调用__getattr__(self, name)
函数吗?
X.__getitem__(1)
在实例和 class 中找不到 __getitem__
所以它调用 __getattr__(self, name)
.
为什么一个工作,一个不工作?我读到特殊方法查找会像 X[1]
一样跳过 __getattr__
函数(如果隐式调用?),但是,在这种情况下我会显式调用它。
special method lookup docs 的最后一部分显示绕过 __getattribute__
时的异常情况。
根据那里的示例(在下面复制)使用 __len__
方法,您代码中的 type(X).__getitem__
会调用元 class 中的 __getattribute__
,但是您还没有定义它。
>>> class Meta(type):
... def __getattribute__(*args):
... print("Metaclass getattribute invoked")
... return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
... def __len__(self):
... return 10
... def __getattribute__(*args):
... print("Class getattribute invoked")
... return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__() # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c) # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c) # Implicit lookup
10
使用此信息,可以解释观察到的行为:
X.__getitem__(1) # <-- works!
__getattribute__
从 class C
被调用来查找 __getitem__
,它 returns 将 __getitem__
绑定到字符串 "spam"
.当使用参数 1 调用时,返回位置 1 的字母 p
。
但是:
type(X).__getitem__(X, 1)
__getattribute__
来自 C
的 metaclass 将被调用,但它没有在那里定义。结果是 AttributeError
.
class C:
data = 'spam'
def __getattr__(self, name):
print('getattr:', name)
return getattr(self.data, name)
X = C()
X.__getitem__(1) // <-- works!
type(X).__getitem__(X, 1) // <-- AttributeError: type object 'C' has no attribute '__getitem__'
既然type(X).__getitem__(X, 1)
在class C中找不到__getitem__
方法,难道不应该调用__getattr__(self, name)
函数吗?
X.__getitem__(1)
在实例和 class 中找不到 __getitem__
所以它调用 __getattr__(self, name)
.
为什么一个工作,一个不工作?我读到特殊方法查找会像 X[1]
一样跳过 __getattr__
函数(如果隐式调用?),但是,在这种情况下我会显式调用它。
special method lookup docs 的最后一部分显示绕过 __getattribute__
时的异常情况。
根据那里的示例(在下面复制)使用 __len__
方法,您代码中的 type(X).__getitem__
会调用元 class 中的 __getattribute__
,但是您还没有定义它。
>>> class Meta(type):
... def __getattribute__(*args):
... print("Metaclass getattribute invoked")
... return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
... def __len__(self):
... return 10
... def __getattribute__(*args):
... print("Class getattribute invoked")
... return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__() # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c) # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c) # Implicit lookup
10
使用此信息,可以解释观察到的行为:
X.__getitem__(1) # <-- works!
__getattribute__
从 class C
被调用来查找 __getitem__
,它 returns 将 __getitem__
绑定到字符串 "spam"
.当使用参数 1 调用时,返回位置 1 的字母 p
。
但是:
type(X).__getitem__(X, 1)
__getattribute__
来自 C
的 metaclass 将被调用,但它没有在那里定义。结果是 AttributeError
.