Here is a snippet of example from Mark Lutz's book "Learning Python". I found it difficult to understand as to how name accesses are translated into getattr() calls in the metaclass:
>>> 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
I have the following questions:
how does B.upper() yield 'SPAM'? Is it because B.upper() =>
A.__getattr__(B, upper())
=> getattr(B.data, upper())? but a call like getattr('spam', upper()) gives error "NameError: name 'upper' is not defined"what path does B.upper go to yiled
<built-in method upper of str object at 0x029E7420>
. does it go through getattr too, what is the true value of the arguments?Does B.append(4) go through
A.__getattr__(cls, name)
? if it does, what is the true values of the arguments in getattr(cls.data, name) in this case?how does
B.__getitem__(0)
yield 1? what is the true values of the arguments in getattr(cls.data, name) in this case?