2012-08-29 17 views
9

प्रिय अजगर 3 विशेषज्ञों के python3 समारोह,को Python2 बनाम विधि बाध्यकारी

को Python2 साथ, एक (मैं जानता हूँ कि यह एक बिट बालों है, लेकिन उस समय यहाँ नहीं है: पी): निम्नलिखित कर सकता है

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 

पायथन 3 के साथ, कोई और अनबाउंड विधियां नहीं हैं, केवल फ़ंक्शंस हैं। अगर मैं एक ही व्यवहार करना चाहते हैं, यह लग रहा है जैसे मैं एक कस्टम वर्णनकर्ता लागू करने के लिए इस तरह के रूप है:

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 में ऑब्जेक्ट से प्राप्त करने की आवश्यकता नहीं है। यह हमेशा निहित किया जाता है। जांचने के लिए, बस प्रिंट करें (anyobject .__ mro __) '(= विधि समाधान आदेश) – cfi

+0

मेरा मानना ​​है कि यह एक प्रतिलिपि है [http://stackoverflow.com/questions/10729909/convert-builtin-function-type-to-method -प्रकार-इन-अजगर-3]। हालांकि यह सवाल शायद ढूंढना आसान है। इसके अलावा यह अधिक स्पष्ट है (कम से कम मेरे लिए), इसलिए मैं इसे रखने के लिए वोट दूंगा ... – cfi

+0

@cfi, ऑब्जेक्ट विरासत के बारे में सही, निश्चित UnboundMethod कोड नमूना। साथ ही आप सही हैं कि एक संकलित/निर्मित फ़ंक्शन को बाध्य करने के लिए एक समान प्रश्न है (जिसमें कोई संतोषजनक उत्तर बीटीडब्ल्यू नहीं है) – sthenault

उत्तर

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

b = B() 
b.method() 

लाइन b.method() तो कॉल A.method(b,A())। इसका मतलब है कि ए को हर बार शुरू किया जाता है। इससे बचने के लिए:

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

अब हर बार जब आप b.method() एक का एक ही उदाहरण दूसरा तर्क के रूप में पारित हो जाता है बी के किसी भी मामले पर कॉल करें।

0

ठीक है, आपका कोड पाइथन 2 में भी काम नहीं करता है, लेकिन मुझे वह करने की कोशिश है जो आप करने की कोशिश कर रहे हैं। और आप लेम्डा का उपयोग कर सकते हैं, जैसे शीना के जवाब में, या 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> 
संबंधित मुद्दे