user6774416 user6774416 - 28 days ago 22
Python Question

Setting attributes on __func__

In the documentation on instance methods it states that:


Methods also support accessing (but not setting) the arbitrary function attributes on the underlying function object.


But I can't seem to be able to verify that restriction. I tried setting both an arbitrary value and one of the "Special Attributes" of functions:

class cls:
def foo(self):
f = self.foo.__func__
f.a = "some value" # arbitrary value
f.__doc__ = "Documentation"
print(f.a, f.__doc__)


When executed, no errors are produced and the output is as expected:

cls().foo() # prints out f.a, f.__doc__


What is it that I'm misunderstanding with the documentation?

Answer

You are misunderstanding what is being said. It says that you can access but not set the attributes of the underlying function object from the method!

>>> class Foo:
...     def foo(self):
...         self.foo.__func__.a = 1
...         print(self.foo.a)
...         self.foo.a = 2
... 
>>> Foo().foo()
1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in foo
AttributeError: 'method' object has no attribute 'a'

Note how foo.a is updated when you set it on the __func__ value, but you cannot set it directly using self.foo.a = value.

So the function object can be modified as you please, the method wrapper only provides read-only access to the attributes on the underlying function.