Extending built-in classes in python

How can I extend an inline class in python? I would like to add a method to the str class.
I did some searches, but all I find are old posts, I hope someone knows something new.

+27
python string monkeypatching
Dec 09 '08 at 12:01
source share
4 answers

Just a subclass of 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_method ValueError: invalid literal for int() with base 10: 'Hi Mom' >>> z = X("271828") >>> z.lower() '271828' >>> z.my_method() 271828 
+26
Dec 09 '08 at 12:08
source share

One way could be to use the concept of "re-opening a class" (originally existing in Ruby), which can be implemented in Python using a class decorator. An example is given on this page: http://www.ianbicking.org/blog/2007/08/opening-python-classes.html

I quote:

I think with class decorators you can do this:

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

Implemented as follows:

 def extend(class_to_extend): def decorator(extending_class): class_to_extend.__dict__.update(extending_class.__dict__) return class_to_extend return decorator 
+11
09 Oct '15 at 8:37
source share

Assuming you cannot modify inline classes. To simulate a “class reopening”, for example Ruby in Python3, where __dict__ is a mappingproxy object, not a 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 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 

I could also write the decorator function 'open':

 def open(cls): def update(extension): namespace = dict(cls.__dict__) namespace.update(dict(extension.__dict__)) return type(cls.__name__,cls.__bases__,namespace) return update 
0
Sep 26 '16 at 17:39
source share

assuming you want to extend the str class by introducing a new hellow_world () method, you can do it like this

 >>> class my_string(str): ... def hello_world(self): ... print "Hello World" ... >>> s = my_string() >>> s.hello_world() Hello World 

If in a newly introduced method you need to use methods from the parent class, for example, you want to define a double_count method that will return twice the number of a given character, you can do

 >>> class my_string(str): ... def double_count(self, c): ... return super(my_string, self).count(c) * 2 >>> s = my_string("abcd") >>> print s.double_count("a") 2 

Hope you find this post helpful.

-one
Aug 15 '18 at 17:56
source share



All Articles