tja*_*son 24 python inheritance python-3.x
假设A是父类,B并且b是其实例B.然后A可以使用super:调用override方法super(B, b).method().
文档在其基本调用中声明" str(object)返回object.__str__()".
它应该遵循str(super(B, b)) == super(B, b).__str__(),但事实并非如此(交互式版本):
class A:
def __str__(self):
return "A"
class B(A):
def __str__(self):
return "B"
b = B()
b_super = super(B, b)
print(str(b_super)) # "<super: <class 'B'>, <B object>>"
print(b_super.__str__()) # "A"
Run Code Online (Sandbox Code Playgroud)
那我哪里出错了?超级机制不适用于魔术方法吗?难道str不能调用__str__在这种情况下?它与本段有关:
请注意,它
super()是作为显式点状属性查找的绑定过程的一部分实现的,例如super().__getitem__(name).它通过实现自己的__getattribute__()方法以可预测的顺序搜索类来支持协作多重继承.因此,super()对于使用语句或运算符(例如)的隐式查找,未定义super()[name].
MSe*_*ert 22
str()不__str__通过常规属性查找过程查找方法.相反,它以MRO顺序直接搜索其参数的层次结构__str__的__dict__s中的方法.这找到了,这给了.super.__str__"<super: <class 'B'>, <B object>>"
但是,当您b_super.__str__手动查找时,super.__getattribute__钩子会super使用它来提供其特殊的属性查找行为.查找__getattribute__将解析A.__str__并调用它.
考虑这个类,它说明了差异(我希望):
class B(object):
def __init__(self, other):
self.other = other
def __getattribute__(self, name):
if name == 'other':
return object.__getattribute__(self, 'other')
elif name == '__str__':
return getattr(self.other, name)
else:
return name
def __str__(self):
return 'fun'
>>> str(B(1)) # calls B.__str__ because it doesn't invoke __getattribute__
'fun'
>>> B(1).__str__() # calls B.__getattribute__ to look up the __str__ method which returns (1).__str__
'1'
Run Code Online (Sandbox Code Playgroud)
在这种情况下同样存在的问题super是这些是依赖于__getattribute__转发它的代理.因此,任何不经历的功能或方法__getattribute__都不会转发.而且str()就是这样一个功能.
只是为了完整性,因为在评论和其他答案中提到了它.
但str(x)并不等同于type(x).__str__(x)因为str()甚至避免了"类上的函数"的正常属性查找过程.它只检查类的tp_str(或者如果是NULL tp_repr)插槽.所以它甚至没有调用__getattribute__元类,它type(x).__str__(x)会做:
class A(type):
def __getattribute__(self, name):
print(name)
if name == '__str__':
return lambda self: 'A'
else:
return type.__getattribute__(self, name)
class B(metaclass=A):
def __str__(self):
return 'B'
>>> b = B()
>>> str(b)
'B'
>>> type(b).__str__(b)
__str__
'A'
Run Code Online (Sandbox Code Playgroud)
然而,在缺少元类的情况下,将其str(x)视为等效可能会有所帮助type(x).__str__(x).但虽然(可能)有帮助,但这是不正确的.
| 归档时间: |
|
| 查看次数: |
821 次 |
| 最近记录: |