Python:检查方法是否是静态的

Dan*_*ung 13 python static-methods

假设以下类定义:

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

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

a = A() 
Run Code Online (Sandbox Code Playgroud)

所以f是常规方法,g是静态方法.

现在,我如何检查ffion对象af和ag是否是静态的?Python中有"isstatic"功能吗?

我必须知道这一点,因为我有包含许多不同函数(方法)对象的列表,并且要调用它们我必须知道它们是否期望"自我"作为参数.

Rom*_*huk 15

让我们试验一下:

>>> import types
>>> class A:
...   def f(self):
...     return 'this is f'
...   @staticmethod
...   def g():
...     return 'this is g'
...
>>> a = A()
>>> a.f
<bound method A.f of <__main__.A instance at 0x800f21320>>
>>> a.g
<function g at 0x800eb28c0>
>>> isinstance(a.g, types.FunctionType)
True
>>> isinstance(a.f, types.FunctionType)
False
Run Code Online (Sandbox Code Playgroud)

所以看起来你可以types.FunctionType用来区分静态方法.


Azm*_*sov 13

为了补充这里的答案,在 Python 3 中最好的方法是这样的:

import inspect

class Test:
    @staticmethod
    def test(): pass

isstatic = isinstance(inspect.getattr_static(Test, "test"), staticmethod)
Run Code Online (Sandbox Code Playgroud)

我们使用getattr_static而不是getattr,因为getattr将检索绑定的方法或函数,而不是staticmethod类对象。classmethod您可以对类型和进行类似的检查property(例如使用@property装饰器定义的属性)

从技术上讲,任何方法都可以用作“静态”方法,只要它们是在类本身上调用的,所以请记住这一点。例如,这将工作得很好:

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

Test.test()
Run Code Online (Sandbox Code Playgroud)

该示例不适用于的实例Test,因为该方法将绑定到实例并调用 as Test.test(self)

在某些情况下,实例和类方法也可以用作静态方法,只要正确处理第一个参数即可。

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

Test.test(None)
Run Code Online (Sandbox Code Playgroud)

也许另一种罕见的情况是 astaticmethod也绑定到类或实例。例如:

class Test:
    @classmethod
    def test(cls): pass

Test.static_test = staticmethod(Test.test)
Run Code Online (Sandbox Code Playgroud)

虽然从技术上讲它是 a staticmethod,但它的行为确实像 a classmethod。因此,在您的自省中,您可以考虑检查__self__(递归地__func__)以查看该方法是否绑定到类或实例。

对于那些进行更深入内省的人来说,另一个最后的警告是 astaticmethod可以在不同的类中定义。这__qualname__将显示静态方法是否在其附加的类中定义。


Jir*_*iri 12

你的方法对我来说似乎有点瑕疵,但你可以检查类属性:

(在Python 2.7中):

>>> type(A.f)
<type 'instancemethod'>
>>> type(A.g)
<type 'function'>
Run Code Online (Sandbox Code Playgroud)

或Python 3.x中的实例属性

>>> a = A()
>>> type(a.f)
<type 'method'>
>>> type(a.g)
<type 'function'>
Run Code Online (Sandbox Code Playgroud)

  • @DuckPuncher在Python 3中,您可以检查`isinstance(A .__ dict __ ['f'],types.FunctionType)`和`isinstance(A .__ dict __ ['g'],staticmethod) (3认同)
  • 请注意,这只有在实例化对象时才起作用(至少在python 3中),因此如果要在不实例化对象的情况下检查方法是否为静态,那么这将不起作用. (2认同)

Mac*_*nhe 5

我碰巧有一个模块可以解决这个问题。它是Python2/3兼容的解决方案。它允许使用从父类继承的方法进行测试。

另外,该模块还可以测试:

  1. 常规属性
  2. 属性样式方法
  3. 常规方法
  4. 静态法
  5. 类方法

例如:

class Base(object):
    attribute = "attribute"

    @property
    def property_method(self):
        return "property_method"

    def regular_method(self):
        return "regular_method"

    @staticmethod
    def static_method():
        return "static_method"

    @classmethod
    def class_method(cls):
        return "class_method"

class MyClass(Base):
    pass
Run Code Online (Sandbox Code Playgroud)

这是仅 staticmethod的解决方案。但我建议使用此处发布的模块

class Base(object):
    attribute = "attribute"

    @property
    def property_method(self):
        return "property_method"

    def regular_method(self):
        return "regular_method"

    @staticmethod
    def static_method():
        return "static_method"

    @classmethod
    def class_method(cls):
        return "class_method"

class MyClass(Base):
    pass
Run Code Online (Sandbox Code Playgroud)