What is the difference between the behavior of a static method, normal method and class method?

Asked

Viewed 228 times

1

I’m studying python with OOP and sometimes I feel confused when using a certain method.

class MeuObjeto(object):

    def __init__(self, objeto):
        self.objeto = objeto

    def metodo_normal(self): //sem decorator
       pass

    @staticmethod
    def metodo_estatico():
       pass

    @classmethod
    def metodo_da_classe(cls):
       pass

What I understand most is the classmethod, whenever I want to instantiate an object of the class I must use it, but the others are confusing me.

  • 1

    Rafael, just remember that the method should receive as first parameter the self and the class method cls. In question you put all without arguments and this would become invalid.

  • well noted @Andersoncarloswoss thanks

1 answer

3


As for your confusion:

In almost every case, you need a "normal method": this is - an instance method, with no decorator, that will receive the "self" - an instance of the class, as first parameter.

A class method - which is created with the decorator @classmethod, can be used directly from the class name - not from an instance - in your example, it means you can do:

MeuObjeto.metodo_da_classe() 

directly, while for the normal method, it is necessary

obj = MeuObjeto()
obj.metodo_normal

Python passes in the first parameter of a class method the class itself - so by convention, the name of the first parameter is "cls". Just as "self" is by convention too - there is no language rule that limits the name of these parameters, and it is normal in decorators, or depending on the code style find methods with the signature *args, **kwargs - in this case, the first parameter will come as the first element of args.

Class methods make more sense precisely when you want different forms of creating class objects - they are often "alternative constructors". They can be called from an instance as well - Python will automatically place the class, not the instance, in the first parameter.

Let’s assume that you had a Table class that is started by a "list list" received on __init__. Could have a classy method from_csv to read a CSV file and create a "Table" with the data read from the CSV file. It’s a much better design than putting a lot of optional parameters on __init__, but on the other hand, may not have many advantages over a function created as def nova_tabela_a_partir_de_csv(caminho_do_csv): - to read the file and create the new Tabela with the data read.

There are other uses - for example, in my "finished" project, the Blockchars_ class basically serves to group some data structures and functions that use them, in the same place -the class has essentially the same role as a Python module, but by making use of classmethods, all the members she needs are grouped in the class body. The exception is the special method __contains__, that the class is unstable - check out the code in https://github.com/jsbueno/terminedia/blob/master/terminedia.py#L204

Static methods, created in Python as @staticmethod, I believe that it even has something corresponding in object orientation theory - a function marked as "staticmethod" in the body of a class is simply a function - Python will not pass any more parameters when it is called - not the instance, not the class - all parameters must be provided by whoever uses the function.

The only thing that happens is that it is "stored" within the class. any method which, although having operations related to the object, does not require any data of the object or class, could be a staticmethod - but sometimes it doesn’t even make sense to go on declaring staticmethods - the method can be left as normal or class method.

Still on the project terminedia i have some methods of that kind - the internal "print" itself on https://github.com/jsbueno/terminedia/blob/55f830e714208c978f36adc117c56804f8e92706/terminedia.py#L307 , only uses the self to call itself recursively, in the event of failure - could perfectly be a static function that called ScreenComands.print - since no instance attribute, or other method is called. But that would only be a "stone" in architecture - it would work as it is, but if tomorrow I make an adaptation of this class to work simultaneously on several terminals, and need distinct instances of "Screencommands", a staticmethod then would stop working.

In short, as a rule, it is best not to use @staticmethod unless you know exactly what you’re doing (and in that case, you’ll realize you don’t need to)

  • Now it’s a little clearer @jsbueno . Thank you very much

Browser other questions tagged

You are not signed in. Login or sign up in order to post.