I bumped into this behaviour when trying to get class-decorators and method-decorators to play nicely together. Essentially, the method decorators would flag some of the methods as special with some dummy value, and the class decorator would come by after and fill in the value later. This is a simplified example
>>> class cow:
>>> def moo(self):
>>> print 'mooo'
>>> moo.thing = 10
>>>
>>> cow.moo.thing
10
>>> cow().moo.thing
10
>>> cow.moo.thing = 5
AttributeError: 'instancemethod' object has no attribute 'thing'
>>> cow().moo.thing = 5
AttributeError: 'instancemethod' object has no attribute 'thing'
>>> cow.moo.__func__.thing = 5
>>> cow.moo.thing
5
Does anyone know why cow.moo.thing = 5
does not work, even though cow.moo.thing
quite clearly gives me 10? And why cow.moo.__func__.thing = 5
works? I have no idea why it does, but in randomly fiddling with stuff in the dir(cow.moo)
list trying to get something to work it suddenly did, and i have no idea why.
cow().moo.thing = 5
is returningAttributeError: 'method' object has no attribute 'thing'
. Do you know why ? – Fleabag