簡體   English   中英

查找舊式Python類的魔術方法

[英]Lookup of magic methods on old-style Python classes

我知道不再推薦舊式Python類,特別是因為Python 3刪除了它們。 但是,我仍然想了解這里發生的事情:

class MyClass:
  pass

my_instance = MyClass()
str(my_instance)

此代碼段打印以下內容:

'< main .MyClass實例位於0x108ec4290>'

所以,我沒有任何顯式繼承,我沒有重載str方法。 但是,這並沒有引起所謂的遺漏方法的異常。 為什么?

我知道舊式課程具有“實例”和“類型”的概念,新式課程旨在統一這些概念。 那么Python是否在我的實例隱式連接的'instance'類型上查找和調用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']

任何人都可以准確地解釋舊式課程中的類和類型之間的關系以及這里發生了什么?

我相信其他人可以給你更具體的理由,但這里有一個類似討論的引用: 舊式的

object是任何繼承樹頂部的基類。 我認為,堅持基類的目的是統一對象行為,而不需要太多的“魔力”。 也就是說,在新式類之前,對象只是神奇地擁有像__doc____str__這樣的屬性; 現在,他們有他們是有原因的:因為他們從基類繼承了它們。

關於“神奇”的那一部分,我相信只是......黑盒魔術。 顯然,舊樣式類的MRO(方法解析順序)更加神奇,因為它可能必須檢查instance對象上的顯式定義以及type 要么,或者舊樣式類的一部分機制是在無法定位時始終提供默認的__str__方法。

現在使用新式類會不那么神奇,因為由於繼承,這些方法實際上就在那里。

這是另一個網站,有一些很好的引用和例子: 最大的驚喜原則

對於舊式類,所有查找都在實例中完成。

對於新式類的實例,所有特殊方法查找都是在類結構中完成的

新風格:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM