Here is a minimum example of a class that holds a function as an attribute and has a method that is calling said function.
class MyClass:
def __init__(self, f):
self.f = f
def func(self):
"""This is the docstring to be replaced."""
return self.f()
The function f can change during runtime and I would like to dynamically change the docstring of func to reflect the current function stored in f.
I was thinking of achieving this by using properties and setter to change the docstring of func as soon as a new f is assigned.
class MyClass:
def __init__(self, f):
self.f = f
@property
def f(self):
return self._f
@f.setter
def f(self, value):
self._f = value
self.func.__doc__ = value.__doc__
def func(self):
"""This is the docstring to be replaced"""
return self.f()
The usage would be as follows
def func():
"""This is the docstring to be shown"""
return True
obj = MyClass(func)
with the goal that calling help(obj.func) would display "This is the docstring to be shown".
However, it seems like docstrings of instance methods are not replaceable.
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[3], line 1
----> 1 obj = MyClass(func)
Cell In[1], line 4, in MyClass.__init__(self, f)
3 def __init__(self, f):
----> 4 self.f = f
Cell In[1], line 13, in MyClass.f(self, value)
10 @f.setter
11 def f(self, value):
12 self._f = value
---> 13 self.func.__doc__ = value.__doc__
AttributeError: attribute '__doc__' of 'method' objects is not writable
Is there any way of achieving this?
You need to distinguish between the
function-valued class attribute that has a docstring and themethodobject created on demand for the evaluation of the expressionself.func.self.funcandMyClass.funcare not the same object.You'll need to use
type(self)or more explicitlyMyClass.funcin order to change the docstring of the correct object.Keep in mind, though, that this is not a way to create instance-specific doc strings.
MyClass.funcis a single object shared by all instances. The problem before is that given instancesaandbofMyClass, not only area.funcandb.funcdifferentmethodobjects derived from that function, but evenx = a.funcandy = a.funcare separate instances ofmethodderived from the same function.