Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do "static method object" and "class method object" not have "callable types"?

In Python Language Reference, Chapter 3 Datamodel, why is "instance method" listed under "callable types", while "static method object" and "class method object" are listed under "internal types"?

Callable types These are the types to which the function call operation (see section Calls) can be applied ...

Instance methods ...

Internal types A few types used internally by the interpreter are exposed to the user. Their definitions may change with future versions of the interpreter, but they are mentioned here for completeness. ...

Static method objects ...

Class method objects ...

Shouldn't static and class method objects also be callable types?

like image 629
Tim Avatar asked Aug 09 '26 18:08

Tim


2 Answers

No, staticmethod's and classmethods are not callable, no rationale to do so was found.

>>> def foo():
...     print("hello") 
>>> s = staticmethod(foo)
>>> s()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'staticmethod' object is not callable

They are meant to be invoked via the descriptor protocol and (usually) return a callable:

>>> s.__get__(foo)()
hello

this isn't the most common form, though. Usually a descriptor is invoked automatically upon attribute access, as the descriptor how-to states:

A descriptor can be called directly by its method name. For example, d.__get__(obj).

Alternatively, it is more common for a descriptor to be invoked automatically upon attribute access. For example, obj.d looks up d in the dictionary of obj. If d defines the method __get__(), then d.__get__(obj) is invoked according to the precedence rules listed below.

like image 152
Dimitris Fasarakis Hilliard Avatar answered Aug 12 '26 07:08

Dimitris Fasarakis Hilliard


The staticmethod objects are not callable:

Python 3.5.3 (default, Jan 19 2017, 14:11:04) 
[GCC 6.3.0 20170118] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> staticmethod(lambda x: print(x))
<staticmethod object at 0x7f8499f1ebe0>
>>> meth = staticmethod(lambda: print('static method called'))
>>> meth()
Traceback (most recent call last):

However they implement the descriptor protocol method __get__. The __get__ method then returns an actual callable object.

File "<stdin>", line 1, in <module>
TypeError: 'staticmethod' object is not callable
>>> meth.__get__(object, object())()
static method called

When you store the staticmethod object into a class attribute, and then look it up, the __get__ method is called implicitly.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!