Class method differences in Python: bound, unbound and static

后端 未结 13 1115
日久生厌
日久生厌 2020-11-22 08:54

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)         


        
13条回答
  •  旧时难觅i
    2020-11-22 09:35

    Unbound Methods

    Unbound methods are methods that are not bound to any particular class instance yet.

    Bound Methods

    Bound methods are the ones which are bound to a specific instance of a class.

    As its documented here, self can refer to different things depending on the function is bound, unbound or static.

    Take a look at the following example:

    class MyClass:    
        def some_method(self):
            return self  # For the sake of the example
    
    >>> MyClass().some_method()
    <__main__.MyClass object at 0x10e8e43a0># This can also be written as:>>> obj = MyClass()
    
    >>> obj.some_method()
    <__main__.MyClass object at 0x10ea12bb0>
    
    # Bound method call:
    >>> obj.some_method(10)
    TypeError: some_method() takes 1 positional argument but 2 were given
    
    # WHY IT DIDN'T WORK?
    # obj.some_method(10) bound call translated as
    # MyClass.some_method(obj, 10) unbound method and it takes 2 
    # arguments now instead of 1 
    
    # ----- USING THE UNBOUND METHOD ------
    >>> MyClass.some_method(10)
    10
    

    Since we did not use the class instance — obj — on the last call, we can kinda say it looks like a static method.

    If so, what is the difference between MyClass.some_method(10) call and a call to a static function decorated with a @staticmethod decorator?

    By using the decorator, we explicitly make it clear that the method will be used without creating an instance for it first. Normally one would not expect the class member methods to be used without the instance and accesing them can cause possible errors depending on the structure of the method.

    Also, by adding the @staticmethod decorator, we are making it possible to be reached through an object as well.

    class MyClass:    
        def some_method(self):
            return self    
    
        @staticmethod
        def some_static_method(number):
            return number
    
    >>> MyClass.some_static_method(10)   # without an instance
    10
    >>> MyClass().some_static_method(10)   # Calling through an instance
    10
    

    You can’t do the above example with the instance methods. You may survive the first one (as we did before) but the second one will be translated into an unbound call MyClass.some_method(obj, 10) which will raise a TypeError since the instance method takes one argument and you unintentionally tried to pass two.

    Then, you might say, “if I can call static methods through both an instance and a class, MyClass.some_static_method and MyClass().some_static_method should be the same methods.” Yes!

提交回复
热议问题