Как определить атрибуты classmethod и staticmethod класса? - PullRequest
0 голосов
/ 27 ноября 2018

При итерации атрибутов класса я вижу атрибуты @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() == "<unbound method DeprecatedClassWithInit.foo>" И метод класса имеет str() == "<bound method type.bar of <class ...>>"
И метод static имеет str() == <function bab at 1232455>

Является ли это хорошим способом определения атрибутов

1 Ответ

0 голосов
/ 27 ноября 2018

Нет, вы не должны полагаться на строковые представления этих атрибутов.Вместо этого обратите внимание, что classmethod и staticmethod являются типами , т.е. они являются объектами класса.Для тех, кто хочет знать, они реализованы в виде дескрипторов.Просто переберите атрибуты класса и используйте 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")
...