Python - a function as an attribute of a class becomes a bound method

I noticed that if I define a class attribute equal to a function, when I instantiate this class, the attribute becomes a bound method. Can someone explain to me the reason for this behavior?

In [9]: def func(): ...: pass ...: In [10]: class A(object): ....: f = func ....: In [11]: a = A() In [12]: af Out[12]: <bound method A.func of <__main__.A object at 0x104add190>> In [13]: af() --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-13-19134f1ad9a8> in <module>() ----> 1 af() global af = <bound method A.func of <__main__.A object at 0x104add190>> TypeError: func() takes no arguments (1 given) 
+7
python methods
source share
2 answers

You have assigned the function to the f attribute. Because the function is now inside the class, it becomes a method, in particular a related method (cause the restriction of the object, further explanation here ).

Methods in classes receive at least one parameter ( self ), unless he specifically says - see class methods and static methods - for this reason the error says that func does not accept arguments (as defined by def func(): but gets 1 ( self )

To do what you want, you must tell python that you are using a static method

 def func(): pass class A(object): f = staticmethod(func) 
+7
source share

Python is not a message-based OO system 1 . Instead, like JavaScript, properties are resolved for first-class functions, and then called; The behavior is slightly different in mechanics such as those found.

In Python, the requirement is that methods have at least one parameter, usually called self , that will be automatically passed by the associated instance when it is called as a method.

Additionally (and possibly to the point of the question), Python does not distinguish between using def f.. or f = some_func() when setting the bindings of instance elements; perhaps this corresponds to behavior outside of classes.

In this example, assigning a function to an instance "makes it wait for processing as an instance method." This is the same — without parameters — a function called in both cases; only appropriate future use matters.

Now, unlike JavaScript, Python processes methods and object associations through the concept of related methods — functions that are allowed as methods are always “connected”.

The af behavior, which returns the bound function, which automatically passes the bound object to the first parameter as self is executed regardless of the source of the function. In this case, this means that a function without parameters cannot be used when it is “connected”, because it does not accept the self parameter.

As a demonstration, the following will crash in the same way, since the original base method does not meet the minimum requirements for taking an instance as an argument:

 g = af g() 

In this case, calling g() equivalent to calling func(a) .


1 For comparison, Java, C #, Ruby, and SmallTalk are message-based OO systems - this object suggests invoking a method by name, rather than allowing a method (or function) as a value that can be called.

+1
source share

All Articles