Adding attributes to instancemethods in Python

instance-method, python

Solution

For attribute lookup, Python is automatically using the real function attached to the instance method for you.

For attribute setting, it is not.

They are two separate operations depending on which side of the statement you're on, even though they both use the `.` operator.

When you access an instance method's `__func__`, you're manually accessing the real function that actually has the `moo` attribute.

In Python 3 this will work as you would like / expect as methods are basically just functions.

Problem

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.

Original source