gpt4 book ai didi

python - 在旧式 Python 类上查找魔法方法

转载 作者:行者123 更新时间:2023-11-28 18:51:34 25 4
gpt4 key购买 nike

我知道不再推荐旧式 Python 类,特别是因为 Python 3 删除了它们。但是,我仍然想了解这里发生了什么:

class MyClass:
pass

my_instance = MyClass()
str(my_instance)

此代码段打印以下内容:

'<ma​​in.MyClass 实例在 0x108ec4290>'

因此,我没有任何显式继承,也没有重载 str 方法。但是,这不会引发所谓缺失方法的异常。为什么?

我知道旧式类具有“实例”和“类型”的概念,而新式类旨在统一这些概念。那么 Python 是否在我的实例隐式连接到的“实例”类型上查找并调用 str 方法?

这里有一些线索:

dir(my_instance) - 返回:

['__doc__', '__module__']

type(my_instance) - 返回:

<type 'instance'>

dir(type(my_instance)) - 返回:

['__abs__', '__add__', '__and__', '__call__', '__class__', '__cmp__', '__coerce__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__div__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__hex__', '__iadd__', '__iand__', '__idiv__', '__ifloordiv__', '__ilshift__', '__imod__', '__imul__', '__index__', '__init__', '__int__', '__invert__', '__ior__', '__ipow__', '__irshift__', '__isub__', '__iter__', '__itruediv__', '__ixor__', '__le__', '__len__', '__long__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__xor__', 'next']

谁能准确解释旧式类中类和类型之间的关系以及这里发生了什么?

最佳答案

我相信其他人可以为您提供更具体的理由,但此处有类似讨论的引述:old-style class

object is the base class that is at the top of any inheritance tree. The purpose of insisting on the base class, I believe, is to unify object behavior without requiring too much 'magic.' That is, prior to new-style classes, objects just magically had properties like __doc__ and __str__; now, they have them for a reason: because they inherited them from the base class.

我认为关于“魔法”的那部分只是……黑盒魔法。显然,旧式类的 MRO(方法解析顺序)更神奇,因为它可能必须检查 instance 上的两个显式定义。对象,以及 type .或者,旧样式类的部分机制是始终提供默认值 __str__无法定位时的方法。

现在使用新型类就没那么神奇了,因为由于继承,方法确实就在实例上。

这是另一个有一些很好的引用和例子的网站:Principle of Biggest Surprise

For old-style classes all lookup is done in the instance.

For instances of new-style classes, all special method lookup that is done implicitely is done in the class struct

新风格:

class Foo(object):
def __str__(self):
return "old str"

foo = Foo()
foo.__str__ = lambda: "new str"

print str(foo)
print foo.__str__()

# old str
# new str

旧式:

class Foo:
def __str__(self):
return "old str"

foo = Foo()
foo.__str__ = lambda: "new str"

print str(foo)
print foo.__str__()

# new str
# new str

关于python - 在旧式 Python 类上查找魔法方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12223836/

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