Python: check if method is static

前端 未结 5 1136
梦谈多话
梦谈多话 2020-12-06 16:48

assume following class definition:

class A:
  def f(self):
    return \'this is f\'

  @staticmethod
  def g():
    return \'this is g\'

a = A() 

5条回答
  •  鱼传尺愫
    2020-12-06 16:57

    To supplement the answers here, in Python 3 the best way is like so:

    import inspect
    
    class Test:
        @staticmethod
        def test(): pass
    
    isstatic = isinstance(inspect.getattr_static(Test, "test"), staticmethod)
    

    We use getattr_static rather than getattr, since getattr will retrieve the bound method or function, not the staticmethod class object. You can do a similar check for classmethod types and property's (e.g. attributes defined using the @property decorator)

    Note that even though it is a staticmethod, don't assume it was defined inside the class. The method source may have originated from another class. To get the true source, you can look at the underlying function's qualified name and module. For example:

    class A:
        @staticmethod:
        def test(): pass
    
    class B: pass
    B.test = inspect.getattr_static(A, "test")
    
    print("true source: ", B.test.__qualname__)
    
    

    Technically, any method can be used as "static" methods, so long as they are called on the class itself, so just keep that in mind. For example, this will work perfectly fine:

    class Test:
        def test():
            print("works!")
    
    Test.test()
    

    That example will not work with instances of Test, since the method will be bound to the instance and called as Test.test(self) instead.

    Instance and class methods can be used as static methods as well in some cases, so long as the first arg is handled properly.

    class Test:
        def test(self):
            print("works!")
    
    Test.test(None)
    

    Perhaps another rare case is a staticmethod that is also bound to a class or instance. For example:

    class Test:
        @classmethod
        def test(cls): pass
    
    Test.static_test = staticmethod(Test.test)
    

    Though technically it is a staticmethod, it is really behaving like a classmethod. So in your introspection, you may consider checking the __self__ (recursively on __func__) to see if the method is bound to a class or instance.

提交回复
热议问题