2011-08-01 69 views
2

爲什麼PEP-343在這種情況下使用type()?使用類型()進行方法調用

mgr = (EXPR) 
    exit = type(mgr).__exit__ # Not calling it yet 
    value = type(mgr).__enter__(mgr) 

我們能不能就如用exit = mgr.__exit__value = mgr.__enter__()?似乎對我來說更簡單,但我認爲我錯過了一些東西。

回答

5

當然PEP 可能使用來使用實例本身的屬性而不是類型的屬性,但這與在Python中使用特殊方法相反。例如

a + b 

被轉換爲

type(a).__add__(a, b) 

a.__add__(b) 

如由以下示例:

>>> class MyInt(int): 
...  pass 
... 
>>> a = MyInt(3) 
>>> b = MyInt(4) 
>>> a + b 
7 
>>> a.__add__ = lambda self, other: 42 
>>> a + b 
7 

所以,叔o與Python的其餘部分保持一致,首先應在類型字典中查找特殊方法__enter__()__exit__()

+0

好吧,所以這只是一個約定,如果有人更改實例__dict__,我們仍然會調用原始函數。甚至沒有想到 - 還沒有找到我想要這樣做的情況;)但是如果有人這樣做,會導致一些奇怪的行爲,所以它是有道理的。 – Voo

+1

@Voo:約定的基本原理並不是避免奇怪的行爲 - 你仍然可以用實時類型'a'覆蓋它的類型來覆蓋實例'a'的'__add __()'方法。 __class__ = type(「」,(type(a),),{「__add__」:lambda self,other:42})'。相反,這種行爲的基本原理是性能。特殊的方法不會在類型的'__dict__'中查找。內部類型數據結構提供了指向特殊方法的特殊字段,因此可以更快地查找它們,請參閱http://docs.python.org/extending/newtypes.html#the-basics。 –

+0

你的意思是PyMethodDef數組 - 它仍然需要通過搜索(但可能會更快?)?還是這樣做是爲了讓所有特殊方法都使用一個通用方法,因爲有些方法(如tp_iternext)會從中獲利,因爲這些方法是在PyTypeObject中聲明的? – Voo

2

上述構建體得到mgr對象的類型(類)的未結合方法,否則mgr字典被acessed,你會得到結合的方法。

相關問題