What is the difference between a "function", a "method" and a "related method" in Python 3?

I have observed at least 3 types related to functions in Python 3:

>>> class A(): ... def f(): pass ... >>> Af <function Af at 0x7fcaef304268> >>> A().f <bound method Af of <__main__.A object at 0x7fcaef2fae80 >>> set.union <method 'union' of 'set' objects> 

I am wondering what is the difference between “function”, “method” and “binding method”? Is a "method" equivalent to a type of "unrelated method" in Python 2?

+5
function python python-internals
source share
1 answer

Is a "method" equivalent to a type of "unrelated method" in Python 2?

Kind-a-kind-a. But not really. This is a method_descriptor object defined in C code. This is an unrelated method, but not the kind you found in Python 2.

For Python types written by C, all “methods” are really C functions. The <method 'name' of 'type' objects> object you found is a special object that you can use to call this function defined for the instance and optional arguments, just like the function object for custom Python classes. The object is defined in C in the PyMethodDescr_Type structure. It implements the descriptor protocol , as well as functions.

Python defines several other types of descriptors; if you use __slots__ , each attribute is a descriptor of type member_descriptor (see PyMemberDescr_Type ), and classmethod , property and staticmethod are probably more well-known descriptor objects.

In Python 2, bound and unbound methods are just one type, instancemethod (defined by the PyMethod_Type structure); it will be reported as linked if the __self__ ( im_self ) attribute is __self__ . In Python 3, using a function as a descriptor simply does not create a method object without __self__ set; instead of calling function.__get__() without an instance just returns the function again.

The only reason Python 2 returns unbound methods is to provide type checking; the first argument must be an instance of the class (or its subclass). This didn't matter much for Python code that supports duck printing, so the restriction was removed in Python 3. However, with C code, you cannot use duck print, you still have to restrict the type, and so C types still return a method_descriptor object that applies this restriction.

+5
source share

All Articles