2008-12-09 7 views
20

में बिल्टिन कक्षाओं का विस्तार करना मैं पाइथन में एक बिल्टिन क्लास कैसे बढ़ा सकता हूं? मैं str वर्ग में एक विधि जोड़ना चाहता हूं।
मैंने कुछ खोज की है लेकिन मुझे जो कुछ मिल रहा है वह पुरानी पोस्ट है, मुझे उम्मीद है कि किसी को कुछ नया पता है।पायथन

+0

संभव का डुप्लिकेट [क्या आप पाइथन में कोर प्रकारों पर पैच विधियों को बंद कर सकते हैं?] (http://stackoverflow.com/questions/192649/can-you-monkey-patch-methods-on-core-types-in-python) – jfs

+0

देखें sanxiyn

उत्तर

20

बस प्रकार उपवर्ग

>>> class X(str): 
...  def myMethod(self): 
...    return int(self) 
... 
>>> s=X("Hi Mom") 
>>> s.lower() 
'hi mom' 
>>> s.myMethod() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 3, in myMethod 
ValueError: invalid literal for int() with base 10: 'Hi Mom' 

>>> z=X("271828") 
>>> z.lower() 
'271828' 
>>> z.myMethod() 
271828 
+1

मैं उम्मीद कर रहा था कि मुझे यह नहीं करना पड़ेगा सबक्लास लेकिन कुछ और शोध के बाद मैं इस निष्कर्ष पर पहुंचा हूं कि यह किसी भी अन्य तरीके से संभव नहीं है, इसलिए मैं यह जवाब स्वीकार करूंगा। – UnkwnTech

+1

@Unkwntech: subclassing से बेहतर तरीका कल्पना नहीं कर सकता। गंभीरता से। जो कुछ भी आपके मन में था (बंदरगाह?) कभी भी एक स्पष्ट, सटीक, स्पष्ट उपclass के साथ काम करने के लिए प्रतीत होता है। –

+5

@ एसएलॉट - रुबी के खुले वर्ग और सी # के विस्तार विधियों को ध्यान में आता है। – orip

8

एक तरह से "वर्ग दोबारा खुलने" अवधारणा (मूल रूप से रूबी में मौजूदा) एक वर्ग डेकोरेटर का उपयोग कर पायथन में लागू किया जा सकता है कि उपयोग करने के लिए हो सकता है। एक उदाहरण इस पृष्ठ पर दी गई है: http://www.ianbicking.org/blog/2007/08/opening-python-classes.html

मैं बोली:

मैं कक्षा सज्जाकार के साथ लगता है कि आप ऐसा कर सकता है:

@extend(SomeClassThatAlreadyExists) 
class SomeClassThatAlreadyExists: 
    def some_method(self, blahblahblah): 
     stuff 

इस तरह लागू किया:

def extend(class_to_extend): 
    def decorator(extending_class): 
     class_to_extend.__dict__.update(extending_class.__dict__) 
     return class_to_extend 
    return decorator 
0

यह मानते हुए कि आप बिल्टिन कक्षाएं नहीं बदल सकते हैं। "वर्ग को फिर से खोलने" python3 में रूबी की तरह अनुकरण करने के लिए जहां __dict__ एक mappingproxy वस्तु और नहीं dict वस्तु है:

def open(cls): 
    def update(extension): 
    for k,v in extension.__dict__.items(): 
     if k != '__dict__': 
     setattr(cls,k,v) 
    return cls 
    return update 


class A(object): 
    def hello(self): 
    print('Hello!') 

A().hello() #=> Hello! 

#reopen class A 
@open(A) 
class A(object): 
    def hello(self): 
    print('New hello!') 
    def bye(self): 
    print('Bye bye') 


A().hello() #=> New hello! 
A().bye()  #=> Bye bye 

मैं भी एक डेकोरेटर समारोह 'खुला' के रूप में अच्छी तरह से लिख सकते हैं:

def open(cls): 
    def update(extension): 
    namespace = dict(cls.__dict__) 
    namespace.update(dict(extension.__dict__)) 
    return type(cls.__name__,cls.__bases__,namespace) 
    return update