I would like to change the __str__()
attribute of one of my class's methods.
(Note: Not to be confused with "trying to change the method __str__()
".)
I have a class, MyClass, which has a method 'some_method'. I can change the way MyClass displays itself by:
class MyClass():
def __init__(self): pass
def some_method(self): pass
def __str__(self): return "I'm an instance of MyClass!"
When I instantiate and print MyClass:
print(my_class)
I get:
I'm an instance of MyClass!
When I
print(my_class.some_method)
I get:
<bound method my_class.some_method of <gumble margle object at mumble-jumble>>
I would like to see instead:
some_method in the instance my_class you Dope!
I've tried overriding the str method of some_method
:
def some_method(self):
def __str__(self):
return "You dope!"
But no love.
Attempting to brute-force it in IPython proved no better:
my_class.some_method.__str__ = lambda: "You Dope!"
gave
AttributeError: 'method' object attribute '__str__' is read-only
Is there an easy way to do this programmatically (preferrably in Python 3)?
You'll need to use a custom class instead of a class function:
class CustomFunction(object):
def __init__(self, name):
self.name = name
def __call__(func, self):
# This is the actual function
pass
def __get__(func, instance=None, type_=None):
class CustomMethod(object):
def __init__(self, instance, type_):
self.im_self = instance
self.im_class = type_
def __call__(self, *args, **kw):
return func(self.im_self, *args, **kw)
def __str__(self):
return '{} in the instance {} you Dope!'.format(func.name, self.im_self)
return CustomMethod(instance, type_)
then use this in your class:
class MyClass():
def __init__(self): pass
some_method = CustomFunction('some_method')
Demo:
>>> print MyClass().some_method
some_method in the instance <__main__.MyClass instance at 0x106b5ccb0> you Dope!
This works because functions are descriptors; they return methods when their __get__
method is called.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With