Extending builtin classes in python
Just subclass the type
>>> class X(str):... def my_method(self):... return int(self)...>>> s = X("Hi Mom")>>> s.lower()'hi mom'>>> s.my_method()Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in my_methodValueError: invalid literal for int() with base 10: 'Hi Mom'>>> z = X("271828")>>> z.lower()'271828'>>> z.my_method()271828
One way could be to use the "class reopening" concept (natively existing in Ruby) that can be implemented in Python using a class decorator.An exemple is given in this page:http://www.ianbicking.org/blog/2007/08/opening-python-classes.html
I quote:
I think with class decorators you could do this:
@extend(SomeClassThatAlreadyExists)class SomeClassThatAlreadyExists: def some_method(self, blahblahblah): stuff
Implemented like this:
def extend(class_to_extend): def decorator(extending_class): class_to_extend.__dict__.update(extending_class.__dict__) return class_to_extend return decorator
Assuming that you can not change builtin classes.To simulate a "class reopening" like Ruby in Python3 where __dict__
is an mappingproxy object and not dict object :
def open(cls): def update(extension): for k,v in extension.__dict__.items(): if k != '__dict__': setattr(cls,k,v) return cls return updateclass 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
In Python2 I could also write a decorator function 'open' as well:
def open(cls): def update(extension): namespace = dict(cls.__dict__) namespace.update(dict(extension.__dict__)) return type(cls.__name__,cls.__bases__,namespace) return update