Home python Question on Static Method and Class Method

Question on Static Method and Class Method

Author

Date

Category

  • I want to establish yourself correctly, I understand the Static Method and Class Method.
    If we turn the method to the decorator @Staticmethod , then the declared method will not be treated in any class in which we declared it, and the object to which we created, the question means that I can write this method as a function In the module area?

  • If you wrap the method into the @ClassMethod decorator, then when calling, as I understand it, it will affect all objects created on the basis of this class. Well, for example, let’s say there is a Count field, which considers the total number of objects created or I do not understand everything?


  • Answer 1, Authority 100%

    The difference in what value will be implicitly transmitted to the method as an additional argument.

    class a:
      @Staticmethod.
      DEF Method1 ():
        Print ('Static Method')
      @classmethod.
      Def Method2 (CLS):
        Print ('Class Method', CLS)
      DEF METHOD3 (SELF):
        Print ('REGULAR METHOD', SELF)
    a = a ()
    a.method1 () # Static Method
    A.Method2 () # Class Method & lt; class '__main __. A' & GT;
    A.Method3 () # Regular Method & lt; __ Main __. A Object at 0x7f5eBe7D6128 & gt;
    

    method1 will not be transmitted anything superfluous, in Method2 only the class corresponding to the instance (A ) will be transferred, and in Method3 – instance itself (a ).

    Since the first two methods are not tied to a specific instance, they can also be called on behalf of the class.

    a.method1 () # Static Method
    A.Method2 () # Class Method & lt; class '__main __. A' & GT;
    

    If you try to trigger Method3 This will result in error

    a.method3 () # Typeerror: Method3 () Missing 1 Required Postal Argument: 'Self'
    

    In this case, it will be necessary to specify an instance explicitly

    a.method3 (a) # regular method & lt; __ main __. a Object AT 0x7F0F9CDA10B8 & GT;
    

    If the method decorated Classmethod will be inherited to him as an argument will be transmitted already class heir

    class B (a):
      Pass
    B = B ()
    B.Method2 () # Class Method & lt; class '__main __. b' & gt;
    B.Method2 () # Class Method & lt; class '__main __. B' & gt;
    

    What distinguishes it from the method, decorated staticmethod , which does not know anything about a particular class, on behalf of which (or on behalf of whose name) it was called.

    UPD

    For example, there is a class

    class a:
      Def __init __ (Self, Arg):
        Self.arg = Arg.
      Def __repr __ (Self):
        Return F '{Type (Self) .__ name __} ({Self.arg! R})'
    

    Our task is to automatically save all the created class instances in the list, and subsequently be able to get this list. In the first approximation we get such a solution:

    class a:
      _Instances = []
      Def __init __ (Self, Arg):
        Self.arg = Arg.
        self.get_instances (). Append (Self)
      @Staticmethod.
      DEF Get_INSTANCES ():
        RETURN A._INSTANCES.
      Def __repr __ (Self):
        Return F '{Type (Self) .__ name __} ({Self.arg! R})'
    A (1)
    A ('Test')
    A (1 == 0)
    Print (A.Get_instances ()) # [A (1), A ('Test'), A (False)]
    

    Here Get_instances is called on behalf of the instance, this is possible thanks to the Staticmethod decorator. It would be possible to do without it, and manually call the method on behalf of the class Type (Self) .get_instances () , but the code becomes easier with the decorator.

    Problems begin when the heir class appears

    class B (a):
      Pass
    B (None)
    Print (B.get_instances ()) # [A (1), A ('Test'), A (FALSE), B (None)]
    

    b does not have its own list of instances, and simply displays a higher one. There are also added B .

    .

    Swipe the solution by replacing the list on the dictionary (class, list) .

    class a:
      _Instances = {}
      Def __init __ (Self, Arg):
        Self.arg = Arg.
        self.get_instances (). Append (Self)
      @Staticmethod.
      DEF Get_INSTANCES ():
        Return A._INSTANCES.SETDEFAULT (A, [])
      Def __repr __ (Self):
        Return F '{Type (Self) .__ name __} ({Self.arg! R})'
    Class B (a):
      @Staticmethod.
      DEF Get_INSTANCES ():
        Return B._INSTANCES.SETDEFAULT (B, [])
    A (1)
    A ('Test')
    A (1 == 0)
    Print (A.Get_instances ()) # [A (1), A ('Test'), A (False)]
    B (None)
    Print (B.get_instances ()) # [B (none)]
    

    Now everything works, but in each descendant you need to override the get_instances method, it leads to repetitions and increases the chance to make an error. Here it comes to the rescue ClassMethod

    class a:
      _Instances = {}
      Def __init __ (Self, Arg):
        Self.arg = Arg.
        self.get_instances (). Append (Self)
      @classmethod.
      DEF Get_INSTANCES (CLS):
        Return CLS._INSTANCES.SETDEFAULT (CLS, [])
      Def __repr __ (Self):
        Return F '{Type (Self) .__ name __} ({Self.arg! R})'
    Class B (a):
      Pass
    A (1)
    A ('Test')
    A (1 == 0)
    Print (A.Get_instances ()) # [A (1), A ('Test'), A (False)]
    B (None)
    Print (B.get_instances ()) # [B (none)]
    

    Now any class of descendant will have its own list of copies, and all logic to maintain these lists is described only in the basic class.

    Programmers, Start Your Engines!

    Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

    Recent questions