I thought that the following code would result in an error because as far as I have read, a method in a Python class must either have "self" (or any other label, but "self" by convention) as its first argument, or "cls" or similar if the @classmethod
decorator is used, or none if the @staticmethod
decorator is used.
How come I get no error running this with Python 3.5 in the Terminal, even though test_method
does not meet these requirements? It seems to work fine as a static method, but without the decorator.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
class MyClass:
def test_method(args):
print(args[1])
@staticmethod
def static_method():
print("static_method")
@classmethod
def class_method(cls):
print("class_method")
def main(args):
MyClass.test_method(args)
if __name__ == '__main__':
sys.exit(main(sys.argv))
Output:
$ python3 testscript.py "testing"
$ testing
EDIT:
My question could also be phrased differently, drawing attention away from self
and to @staticmethod
: "How come I'm getting a seemingly working static method without the @staticmethod decorator?"
self represents the instance of the class. By using the “self” we can access the attributes and methods of the class in python. It binds the attributes with the given arguments. The reason you need to use self. is because Python does not use the @ syntax to refer to instance attributes.
Need for Self in Python Python uses the self parameter to refer to instance attributes and methods of the class. Unlike other programming languages, Python does not use the “@” syntax to access the instance attributes. This is the sole reason why you need to use the self variable in Python.
If there was no self argument, the same class couldn't hold the information for both these objects. However, since the class is just a blueprint, self allows access to the attributes and methods of each object in python. This allows each object to have its own attributes and methods.
The self in keyword in Python is used to all the instances in a class. By using the self keyword, one can easily access all the instances defined within a class, including its methods and attributes. __init__ is one of the reserved methods in Python. In object oriented programming, it is known as a constructor.
However, since the class is just a blueprint, self allows access to the attributes and methods of each object in python. This allows each object to have its own attributes and methods.
Self must be provided as a First parameter to the Instance method and constructor. If you don’t provide it, it will cause an error. Self is a convention and not a Python keyword . self is parameter in Instance Method and user can use another parameter name in place of it.
The usual terminology for this is method. So inside a class, each method, when called belongs to only one object. If that object is actually the same class as your current code, you say “I call it from the (current) class itself”. Fortunately Python has shortened that phrase to a single word, self.
But, in Python we have to explicitly declare the object instance as “self” variable. Python self is a keyword? Python self variable is not a reserved keyword. But, it’s the best practice and convention to use the variable name as “self” to refer to the instance.
In Python 2, functions defined in a class body are automatically converted to "unbound methods", and cannot be called directly without a staticmethod decorator. In Python 3, this concept was removed; MyClass.text_method
is a simple function that lives inside the MyClass namespace, and can be called directly.
The main reason to still use staticmethod
in Python 3 is if you also want to call the method on an instance. If you don't use the decorator, the method will always be passed the instance as the first parameter, causing a TypeError.
There is nothing special about this. In python 3 there is no difference between a function defined inside a class or a function defined outside a class. Both of them are normal functions.
The self
that you are talking about here or maybe cls
comes into picture only when you access the function through an instance. Hence here you didn't get any error.
However if you modify your code just a little bit to look like the following, then you'd get an error that you expected.
def main(args):
MyClass().test_method(args)
# Should throw an error
EDIT:
@staticmethod
will work on both class instances like MyClass().test_method(args)
and just a regular direct call like MyClass.test_method(args)
self
in it) can't be called on a class instance. So you will always have to call it as MyClass.test_method(args)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With