Playing around with Python
, I have come across an error type takes 2 positional arguments but 3 were given
. My method, which is inside a class, was of the form
def add(x, y):
return x +y
I had just read the basic documentation on classes and was aware of the @classmethod
and modifiers @staticmethod
, which the documentation says are basically "syntactic sugar" . I also know that self
or cls
are not reserved words, so it doesn't matter if my first parameter is called self
, cls
or x
.
The error obtained makes me think that by default, the methods of a class are considered class methods (and the first argument is considered a reference to the class/instance) and if I want them to be static then I have to put the modifier, but not I've found nothing that explicitly states this in the documentation.
It may seem obvious, but for me it has been quite counterintuitive that if I declare
def saludar() :
print("hola")
inside a class, the call will fail because the function has 0 parameters but we will try to pass one (implicit) with the call. Can someone confirm that methods are class defaults, as if they were annotated with @classmethod
?
The methods of a class, by default, work as follows:
Case 1: Instance Methods
A class without
@classmethod
or@staticmethod
. As you mention,self
orcls
are not reserved words but are suggested to maintain a standard in Object Oriented Programming in Python:Indeed, all methods of a class need to have the reference to the instance. As you can see I'm not even using
self
.This is equivalent, albeit a bit silly, but it demonstrates how a method is called using an instance of the class:
It is not possible to call the method without an instance in between unless you use
@classmethod
as we will see in Case 2 :Case 2: Class Methods
A class with
@classmethod
. By decorating a method with@classmethod
what you're saying to Python is: "Python, just in case I want to use that method without having an instance so don't give me the " nonsenseself
. And Python will tell you: "Ok, but then give me a reference to the class." Again, you don't need to usecls
:This class doesn't even have a constructor, it's a meaningless class that just greets you but you can call it without needing to have an instance of the class. You could do something like this:
What the method
desde_nombre
actually does is return an instance of the class. In this case there is not much science but it is very useful in complex cases in which the received data does not match the parameters of the constructor.Case 3: Static Methods
class with
@staticmethod
.self
In short, what you're saying to Python is "Python, I'm going to create a method with no instance and no class so don't give me the or " nonsensecls
. And Python will reply: "You know you can do that without a class, right?" A con method@staticmethod
is practically an elegant way to call a function from a class, since it receives neither the instance nor the class itself.Personally I have used it a few times but I come across cases in which this method could be closely related to the data you handle in the class and you want to keep everything in the same place. That is, instead of creating a "helper" function in another module, you create it in the same class as some kind of validation:
This is, in short, more or less how classes work in Python.
The methods of a class in Python are by default instance methods, they need a reference to the object in question.
If you look at Wikipedia Method_(computing) , it distinguishes between instance methods and class or static methods , in Python (unlike other languages) class and static methods are two different things. This is because the classes themselves are also objects.
An instance method , in Python, needs an explicit reference to the instance, hence the error
takes 2 positional arguments but 3 were given
. The syntactic sugar is that the interpreter is in charge of passing the reference to the instance as the first parameter of the method, that is why it is necessaryself
in the method declaration but not the reference to the instance when calling the method. of form:instancia.metodo()
.A class method is an instance method of the class object, in Python classes are also objects. To indicate to the interpreter that said method will not belong to the instances of the class but to the class object itself, the @classmethod decorator is necessary . Since every instance method needs a reference to the object on which it is executed, in this case
cls
. As muchself
ascls
they are arbitrary words, but the convention is to use such words, in keeping with the Zen philosophy of Python that there should be only one obvious way to do something . They are generally used as alternative initializers__init__
to .Lastly, a static method is a function (it doesn't need an object or class reference to work) but it needs the @staticmethod decorator so that the interpreter doesn't take it as an instance method.
It looks better with code. If we define the class
Clase
and an instance:Clase
is an object of type type,instancia
is an object of typeClase
:The
metodo_instancia
until that does not belong to an instance of the class is a function, 'function' (In Python 2 it would be an 'unbound method' ):But once it belongs to the instance, it becomes a 'bound method', a method linked to said instance:
The class method
metodo_clase
is a bound method to the class:In both cases it serves as a factory (in our implementation of the class
Clase
) to create new objects of typeClase
:Finally, the
metodo_estatico
is the same function, both in the class and in the instance:In Python, methods are by default instance methods.
In Python there are three types of methods:
static
in other languages.