What is the difference between the following class methods?
Is it that one is static and the other is not?
class Test(object): def method_one(self): print "Called method_one" def method_two(): print "Called method_two" a_test = Test() a_test.method_one() a_test.method_two()
In Python, there is a distinction between bound and unbound methods.
Basically, a call to a member function (like
method_one), a bound function
is translated to
i.e. a call to an unbound method. Because of that, a call to your version of
method_two will fail with a
>>> a_test = Test() >>> a_test.method_two() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: method_two() takes no arguments (1 given)
You can change the behavior of a method using a decorator
class Test(object): def method_one(self): print "Called method_one" @staticmethod def method_two(): print "Called method two"
The decorator tells the built-in default metaclass
type (the class of a class, cf. this question) to not create bound methods for
Now, you can invoke static method both on an instance or on the class directly:
>>> a_test = Test() >>> a_test.method_one() Called method_one >>> a_test.method_two() Called method_two >>> Test.method_two() Called method_two
Methods in Python are a very, very simple thing once you understood the basics of the descriptor system. Imagine the following class:
class C(object): def foo(self): pass
Now let"s have a look at that class in the shell:
>>> C.foo <unbound method C.foo> >>> C.__dict__["foo"] <function foo at 0x17d05b0>
As you can see if you access the
foo attribute on the class you get back an unbound method, however inside the class storage (the dict) there is a function. Why"s that? The reason for this is that the class of your class implements a
__getattribute__ that resolves descriptors. Sounds complex, but is not.
C.foo is roughly equivalent to this code in that special case:
>>> C.__dict__["foo"].__get__(None, C) <unbound method C.foo>
That"s because functions have a
__get__ method which makes them descriptors. If you have an instance of a class it"s nearly the same, just that
None is the class instance:
>>> c = C() >>> C.__dict__["foo"].__get__(c, C) <bound method C.foo of <__main__.C object at 0x17bd4d0>>
Now why does Python do that? Because the method object binds the first parameter of a function to the instance of the class. That"s where self comes from. Now sometimes you don"t want your class to make a function a method, that"s where
staticmethod comes into play:
class C(object): @staticmethod def foo(): pass
staticmethod decorator wraps your class and implements a dummy
__get__ that returns the wrapped function as function and not as a method:
>>> C.__dict__["foo"].__get__(None, C) <function foo at 0x17d0c30>
Hope that explains it.
Cracking the Coding Interview PDF: 189 Programming Questions and Solutions, 6th Edition. I am not a recruiter. I am a software engineer. And as such, I know what it's like to be asked to create ing...
Mastering regular expressions by Jeffrey Friedl, 3rd edition. Regular expressions are an extremely powerful tool for manipulating text and data. They are standard features today in a variety of pop...
Systems programming provides the basis for global calculation. Developing performance-sensitive code requires a programming language that allows programmers to control the use of memory, processor tim...
It would be easy for me to develop native apps using Java, C++ or Objective-C and I am also able to learn Kotlin, Dart or Swift, but things are much easier when you just use Python. I have done a Djan...