gpt4 book ai didi

python - 如何将 __getattr__ 的这个例子理解为元类方法

转载 作者:行者123 更新时间:2023-11-28 16:24:13 29 4
gpt4 key购买 nike

这是 Mark Lutz 的书“学习 Python”中的示例片段。我发现很难理解名称访问如何转换为元类中的 getattr() 调用:

>>> class A(type):
def __getattr__(cls, name):
return getattr(cls.data, name)

>>> class B(metaclass=A):
data = 'spam'
>>> B.upper()
'SPAM'
>>> B.upper
<built-in method upper of str object at 0x029E7420>
>>> B.__getattr__
<bound method A.__getattr__ of <class '__main__.B'>>

>>> B.data = [1, 2, 3]
>>> B.append(4)
>>> B.data
[1, 2, 3, 4]
>>> B.__getitem__(0)
1
>>> B[0]
TypeError: 'A' object does not support indexing

我有以下问题:

  1. B.upper() 如何产生“垃圾邮件”?是不是因为 B.upper() => A.__getattr__(B, upper()) => getattr(B.data, upper())?但是像 getattr('spam', upper()) 这样的调用会给出错误“NameError: name 'upper' is not defined”

  2. B.upper 到 yiled 的路径是什么 <built-in method upper of str object at 0x029E7420> .它是否也通过 getattr,参数的真正值(value)是什么?

  3. B.append(4) 是否经过 A.__getattr__(cls, name) ?如果是,那么在这种情况下,getattr(cls.data, name) 中参数的真实值是多少?

  4. 如何B.__getitem__(0)产量 1?在这种情况下,getattr(cls.data, name) 中参数的真实值是什么?

最佳答案

  1. B.upper() 首先查找 B.upper 然后不带参数调用它。 B.upper 通过按特定顺序尝试多个选项来查找,最终尝试 type(B).__getattr__(B, 'upper'),在本例中为A.__getattr__(B, 'upper'),返回 'spam'.upper
  2. 如上所述,B.upper 经历了几个选项,在本例中达到了 type(B).__getattr__(B, 'upper')A.__getattr__(B, '上')
  3. 是的,在这种情况下,B.append 将到达 A.__getattr__(B, 'append'),后者将返回 B.data.append
  4. B.__getitem__(0) 将在这种情况下查找 B.__getitem__ 并通过 A.__getattr__(B, '__getitem__') 将返回 B.data.__getitem__

另外,请注意最后一个示例 B[0] 不起作用,因为 B 类没有直接定义一个__getitem__ 方法。这是因为“特殊”方法(例如 __getitem__)在通过其特殊语法(例如本例中的 B[0])使用时会以不同方式查找。

关于python - 如何将 __getattr__ 的这个例子理解为元类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37826361/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com