Why does class X work: mypow = pow? How about self?

This works and happily prints 81:

class X: mypow = pow print(X().mypow(3, 4)) 

But why? Doesn't the method give an extra self argument and should be completely confused?

For comparison, I also tried this with my own Pow function:

 def Pow(x, y, z=None): return x ** y class Y: myPow = Pow print(Pow(3, 4)) print(Y().myPow(3, 4)) 

A direct function call prints 81, and the method call fails, as expected, as it receives an additional instance argument:

 Python 3: TypeError: unsupported operand type(s) for ** or pow(): 'Y' and 'int' Python 2: TypeError: unsupported operand type(s) for ** or pow(): 'instance' and 'int' 

Why / how does Pythons Pow here? The documentation did not help, and I could not find the source.

+7
python methods self
source share
2 answers

This is because python functions defined in C (built-in) automatically process their own argument. Here is the pow function header:

static PyObject * math_pow(PyObject *self, PyObject *args) Here you can see that self is always passed by the interpreter.

+5
source share

This behavior is associated with method binding. See what Python tells you about these functions / methods:

 >> pow <built-in function pow> >>> X.mypow <built-in function pow> >>> X().mypow <built-in function pow> 

and

 >>> Pow <function Pow at 0x7f88f5715f50> >>> Y.myPow <unbound method Y.Pow> >>> Y().myPow <bound method Y.Pow of <__main__.Y instance at 0x7f88f57117e8>> 

Further documentation states:

A class dictionary stores methods as functions. In a class definition, methods are written using def and lambda , the usual tools for creating functions. [...]

To support method calls, functions include the __get__() method of the binding methods when accessing the attribute. This means that all functions are non-given descriptors that return related or unrelated methods depending on whether they are called from an object or class. [...]

But inline functions do not have the __get__() method. Therefore, pow not bound and could be used as you observed, but pow could not.

+2
source share

All Articles