【问题标题】:How to determine classmethod and staticmethod attributes of a class?如何确定一个类的classmethod和staticmethod属性?
【发布时间】:2019-04-28 14:37:30
【问题描述】:

在迭代类的属性时,我可以看到@classmethod 和@staticmethod 属性,但我不确定如何根据它们的类型通用地识别它们

class DeprecatedClassWithInit(object):
    def __init__(self):
        pass

    def foo(self):
        return "DeprecatedClassWithInit.foo()"

    @classmethod
    def bar(cls):
        return "DeprecatedClassWithInit.bar(cls)"

    @staticmethod
    def bab():
        return "DeprecatedClassWithInit.bab()"

属性看起来像:

bab = <function bab at 0x7f354f5711b8> (type = <type 'function'>)
bar = <bound method type.bar of <class 'utils.test_decorators.DeprecatedClassWithInit'>> (type = <type 'instancemethod'>)
foo = <unbound method DeprecatedClassWithInit.foo> (type = <type 'instancemethod'>)

所以实例方法有一个str() == "&lt;unbound method DeprecatedClassWithInit.foo&gt;" 而classmethod有str() == "&lt;bound method type.bar of &lt;class ...&gt;&gt;"
而staticmethod有str() == &lt;function bab at 1232455&gt;

这是识别属性的好方法吗?

【问题讨论】:

    标签: python static-methods introspection class-method


    【解决方案1】:

    不,您不应该依赖这些属性的字符串表示。相反,请注意classmethodstaticmethod类型,即它们是类对象。对于那些想知道的人,它们被实现为描述符。只需遍历一个类的属性并使用isinstance

    class DeprecatedClassWithInit(object):
        def __init__(self):
            pass
    
        def foo(self):
            return "DeprecatedClassWithInit.foo()"
    
        @classmethod
        def bar(cls):
            return "DeprecatedClassWithInit.bar(cls)"
    
        @staticmethod
        def bab():
            return "DeprecatedClassWithInit.bab()"
    
    for name, attr in vars(DeprecatedClassWithInit).items():
        if isinstance(attr, classmethod):
            print(name, "is a classmethod")
        elif isinstance(attr, staticmethod):
            print(name, "is a staticmethod")
    

    【讨论】:

    • 类方法的类型(如问题所示)是instancemethod,而不是classmethod。我怀疑类和静态方法涉及一些编译器魔法
    • @RichardHaven 你试过这个吗?有用。这是您在调用描述符协议时获得的类型,因为您已经使用属性访问运算符(即使用点符号)访问了它。使用vars 直接内省属性,避免使用描述符协议,让您可以访问原始描述符。同样,您真的尝试过吗?
    • @RichardHaven,staticmethodclassmethod 没有编译器魔法。正如我所说,它们是实现the descriptor protocol 的类。在该链接中,您将看到一个如何在纯 Python 中实现它们的示例(当然,它们恰好是在 C 中实现的,但这与这里无关)
    • 我试过了。我将在我的生产代码之外尝试它,看看它是否在那里工作得更好
    • @RichardHaven 你的输出到底是怎样的?
    猜你喜欢
    • 2018-04-15
    • 2021-08-14
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 2012-08-24
    相关资源
    最近更新 更多