【问题标题】:Can I extract all methods - instance, classmethods, staticmethods of a class in Python [duplicate]我可以在Python中提取所有方法-实例,类方法,静态方法吗?
【发布时间】:2021-02-13 11:23:35
【问题描述】:

我执行了以下 Python 代码:

class C:
    def m1(self):
        print('method m1')
    def m2(self):
        print('method m2')
    @classmethod
    def m3(cls):
        print('class method')
    @staticmethod
    def m4():
        print('static method')

print()
for key, val in vars(C).items():
    print(key, '***', val, end=' ')
    if callable(val):
        print(True)
    else:
        print(False)

得到以下输出:

__module__ *** __main__ False
m1 *** <function C.m1 at 0x7f3661a62dc0> True
m2 *** <function C.m2 at 0x7f3661a735e0> True
m3 *** <classmethod object at 0x7f3661bd4670> False
m4 *** <staticmethod object at 0x7f3661ab4f10> False
__dict__ *** <attribute '__dict__' of 'C' objects> False
__weakref__ *** <attribute '__weakref__' of 'C' objects> False
__doc__ *** None False

我想知道为什么callable@classmethod@staticmethod 返回False

我实际上是在尝试找出类中所有方法的名称,以便我可以使用用户定义的装饰器来装饰该类的所有方法

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    改用dir(C)getattr()

    class C:
        def m1(self):
            print('method m1')
    
        def m2(self):
            print('method m2')
    
        @classmethod
        def m3(cls):
            print('class method')
    
        @staticmethod
        def m4():
            print('static method')
    
    
    for val in dir(C):
        if callable(getattr(C, val)):
            print('***', val, end=' ')
            print(True)
        else:
            print(val, False)
    

    输出:

    *** __class__ True
    *** __delattr__ True
    __dict__ False
    *** __dir__ True
    __doc__ False
    *** __eq__ True
    *** __format__ True
    *** __ge__ True
    *** __getattribute__ True
    *** __gt__ True
    *** __hash__ True
    *** __init__ True
    *** __init_subclass__ True
    *** __le__ True
    *** __lt__ True
    __module__ False
    *** __ne__ True
    *** __new__ True
    *** __reduce__ True
    *** __reduce_ex__ True
    *** __repr__ True
    *** __setattr__ True
    *** __sizeof__ True
    *** __str__ True
    *** __subclasshook__ True
    __weakref__ False
    *** m1 True
    *** m2 True
    *** m3 True
    *** m4 True
    

    vars(),基本上是类块的locals(),并返回作为普通函数转储的函数。

    m3 *** <classmethod object at 0x1089afbb0>
    m4 *** <staticmethod object at 0x1089afcd0>
    

    getattr() 返回装饰器包装的函数:

    <bound method C.m3 of <class '__main__.C'>>
    <function C.m4 at 0x1050ab940>
    

    【讨论】:

    • 因为 classmethod 和 staticmethod 对象是不可调用的,除非通过访问器(getattr 调用但 vars 不会)访问它们来适当地包装它们。试试vars(C)['m3'](),你会得到一个类型错误,因为它不可调用。
    • 所以实际上我使用上面的代码来识别可以通过用户定义的装饰器装饰的方法。我想装饰所有的方法。但我无法装饰@classmethod@staticmethod。那么有没有办法只在一个类中提取所有方法定义,以便我的用户定义的装饰器只能装饰那些类成员
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-07
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-10
    相关资源
    最近更新 更多