2008-12-09 8 views
20

Python'da yerleşik bir sınıfı nasıl genişletebilirim? str sınıfına bir yöntem eklemek istiyorum.
Bazı aramalar yaptım ama bulduğum her şey daha eski mesajlar, birisinin daha yeni bir şey bilmesini umuyorum.Python'da yerleşik sınıfları genişletme

+0

mümkün __dict__ bir mappingproxy nesne değil dict nesne olduğu Python3 içinde Ruby gibi bir "yeniden açılması sınıfı" taklit etmek [python çekirdek türlerinde Eğer maymun yama yöntemleri Can?] (http://stackoverflow.com/questions/192649/can-you-monkey-patch-methods-on-core-types-in-python) – jfs

+0

See çoğaltmak Ayrıca, Ben olmazdı umuyordum – sanxiyn

cevap

20

Sadece bir sınıf yönetmeni kullanarak Python uygulanabilir "sınıfı yeniden açılmasının" kavramını (doğal Ruby mevcut) kullanmak için olabilir tip

>>> 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

alt sınıf ama daha fazla araştırmadan sonra başka bir şekilde mümkün olmadığı sonucuna vardım, bu yüzden bu cevabı kabul edeceğim. – UnkwnTech

+1

@Unkwntech: Alt sınıflamadan daha iyi bir yol düşünemiyorum. Ciddi anlamda. Aklınızdan geçen her ne ise (maymunluk?) Hiçbir zaman net, kesin, açık bir alt sınıf kadar işe yaramadı. –

+5

@ S.Lott - Ruby'nin açık sınıfları ve C# 'nin uzantı yöntemleri akla geliyor. – orip

8

Tek yön alt sınıfı. Bir exemple bu sayfada verilmiştir: http://www.ianbicking.org/blog/2007/08/opening-python-classes.html

Ben alıntı:

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

böyle Uygulanan: Bunu yapabileceğini

Sınıf dekoratörler ile düşünmek

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

Yerleşik sınıfları değiştiremeyeceğinizi varsayarak.

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 

Ben aynı zamanda 'açık' bir dekoratör fonksiyon yazabiliriz::

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