2012-08-29 85 views
9

親愛的蟒蛇專家3人,python2 VS python3函數方法結合

與python2,一個可以做到以下幾點(我知道這是一個有點毛茸茸的,但在這裏,這不是問題的關鍵:P):

class A(object): 
    def method(self, other): 
    print self, other 

class B(object): pass 

B.method = types.MethodType(A().method, None, B) 
B.method() # print both A and B instances 

與python3,沒有更多的未綁定方法,只有函數。如果我想相同的行爲,這聽起來像我所介紹的自定義描述符,如:

class UnboundMethod: 
    """unbound method wrapper necessary for python3 where we can't turn 
    arbitrary object into a method (no more unbound method and only function 
    are turned automatically to method when accessed through an instance) 
    """ 
    def __init__(self, callable): 
     self.callable = callable 

    def __get__(self, instance, objtype): 
     if instance is None: 
      return self.callable 
     return types.MethodType(self.callable, instance) 

所以我可以做:

B.method = UnboundMethodType(A().method) 
B.method() # print both A and B instances 

是否有任何其他方式做到這一點無需編寫這樣的描述符?

TIA

+0

快速,脫離主題的評論:無需派生自Py3中的對象。它總是隱含的。檢查,只是'print(anyobject .__ mro __)'(=方法解析順序) – cfi

+0

我相信這是一個重複的[http://stackoverflow.com/questions/10729909/convert-builtin-function-type-to-method型合蟒-3]。然而,這個問題可能更容易找到。另外它更清晰(至少對我來說),所以我會投票保留這個... – cfi

+0

@cfi,關於對象繼承的真,修正了UnboundMethod代碼示例。你也是對的,這是一個類似的問題,因爲綁定編譯/內置函數(它沒有滿足答案btw) – sthenault

回答

1
B.method = lambda o: A.method(o,A()) 

b = B() 
b.method() 

b.method()然後調用A.method(b,A())。這意味着每次都會初始化一個A.爲了避免這種情況:

a = A() 
B.method = lambda o: A.method(o,a) 

現在每次你打電話弘()上的一個相同的實例作爲第二個參數傳遞B的任何實例。

0

那麼,你的代碼也不能在Python 2中工作,但我會得到你想要做的。你可以使用lambda,就像在Sheena的回答中,或者functools.partial。

>>> import types 
>>> from functools import partial 

>>> class A(object): 
... def method(self, other): 
...  print self, other 
... 
>>> class B(object): pass 
... 
>>> B.method = partial(A().method, A()) 
>>> B().method() 
<__main__.A object at 0x112f590> <__main__.A object at 0x1132190>