I am working with a Python class, and I don\'t have write access to its declaration.
How can I attach a custom method (such as __str__
) to the
This is my answer from another question:
import types
class someclass(object):
val = "Value"
def some_method(self):
print self.val
def some_method_upper(self):
print self.val.upper()
obj = someclass()
obj.some_method()
obj.some_method = types.MethodType(some_method_upper, obj)
obj.some_method()
>>> class C(object):
... pass
...
>>> def spam(self):
... return 'spam'
...
>>> C.__str__ = spam
>>> print C()
spam
It won't work on classes which use __slots__.
Note that using Alex's subclass idea, you can help yourself a little bit more using "from
... import
... as
":
from datetime import datetime as datetime_original
class datetime(datetime_original):
def __str__(self):
return 'spam'
so now the class has the standard name, but different behaviour.
>>> print datetime.now()
'spam'
Of course, this can be dangerous...
If you create a wrapper class, this will work with any other class, either built-in or not. This is called "containment and delegation", and it is a common alternative to inheritance:
class SuperDuperWrapper(object):
def __init__(self, origobj):
self.myobj = origobj
def __str__(self):
return "SUPER DUPER " + str(self.myobj)
def __getattr__(self,attr):
return getattr(self.myobj, attr)
The __getattr__
method will delegate all undefined attribute requests on your SuperDuperWrapper object to the contained myobj object. In fact, given Python's dynamic typing, you could use this class to SuperDuper'ly wrap just about anything:
s = "hey ho!"
sds = SuperDuperWrapper(s)
print sds
i = 100
sdi = SuperDuperWrapper(i)
print sdi
Prints:
SUPER DUPER hey ho!
SUPER DUPER 100
In your case, you would take the returned object from the function you cannot modify, and wrap it in your own SuperDuperWrapper, but you could still otherwise access it just as if it were the base object.
print sds.split()
['hey', 'ho!']
Create a subclass. Example:
>>> import datetime
>>> t = datetime.datetime.now()
>>> datetime.datetime.__str__ = lambda self: 'spam'
...
TypeError: cant set attributes of built-in/extension type 'datetime.datetime'
>>> t.__str__ = lambda self: 'spam'
...
AttributeError: 'datetime.datetime' object attribute '__str__' is read-only
>>> class mydate(datetime.datetime):
def __str__(self):
return 'spam'
>>> myt = mydate.now()
>>> print t
2009-09-05 13:11:34.600000
>>> print myt
spam