我如何只过滤实例方法 - 而不是 class 方法

how do i filter for only instance methods - not class methods

完成“学习 Python:强大的面向对象编程”

第 28 章让您创建了一个 class 来列出一个对象的所有实例属性。

然后这本书提供了一些想法,例如列出继承树上的所有属性。这样做时,我使用了如下所示的 @classmethod 装饰器 - 想知道是否有办法从我的列表中过滤掉这些类型的方法:

"""Assorted class utilities and tools"""


class ShowAttrs(object):
    """
    A class to show all available (including inherited, excluding special) attributes
    """
    @classmethod
    def getAttrs(cls, child_cls):
        my_attrs = [_ for _ in child_cls.__dict__ if _.startswith('_') is False]
        my_name = child_cls.__name__
        listed_attrs = [my_name + ': ' + ', '.join(my_attrs)]
        try:
            bases = child_cls.__bases__
            inherited_attrs = []
            for base in bases[::-1]:
                if base.__name__ != 'ShowAttrs' and base.__name__ != 'object':
                    inherited_lists = [ShowAttrs.getAttrs(base)]
                    for _ in inherited_lists:
                        inherited_attrs.extend(_)
        except NameError:
            return
        inherited_attrs.extend(listed_attrs)
        return inherited_attrs

    def __repr__(self):
        child_cls = self.__class__
        all_attrs = ShowAttrs.getAttrs(child_cls)
        len_attrs = reversed(list(range(len(all_attrs))))
        all_attrs_unique = [ x for i,x in zip(len_attrs,all_attrs[::-1]) if i <= all_attrs.index(x) ]
        return '\n'.join(reversed(all_attrs_unique))


if __name__ == '__main__':


    class Parent(ShowAttrs):
        var3 = 'Parent'

        def parentMethod(self):
            print('this is a Parent')

    class Child(Parent):
        var2 = 'Child'

        def childMethod(self):
            print('this is a Child')


    class GrandChild(Child):
        var1 = 'GrandChild'

        @classmethod
        def howCanIFilterThisOneOut(cls):
            pass

        def grandchildMethod(self):
            print('this is a GrandChild')

        def grandchildMethod2(self):
            pass

        def grandchildMethod3(self):
            pass

    class GrandChild2(Child):
        var11 = 'GrandChild2'


    class GreatGrandChild(GrandChild, GrandChild2):
        var0 = 'GreatGrandChild'

    x = GreatGrandChild()
    print(x)

当我 运行 这个:

Python 3 x = 曾孙() 打印(x)

Console 
Parent: var3, parentMethod
Child: var2, childMethod
GrandChild2: var11
GrandChild: var1,howCanIFilterThisOneOut, grandchildMethod, grandchildMethod2, grandchildMethod3
GreatGrandChild: var0

但是howCanIFilterThisOneOut是一个class方法,不是实例方法。所以只是想知道是否有可能区分。

谢谢

沙盒试一试: https://edube.org/sandbox/af4390bc-77aa-11ec-ab3f-0242157e55ca

isinstance(x, classmethod) 成功了。

my_attrs = [
  name for (name, value) 
  in child_cls.__dict__.items() 
  if not name.startswith('_') and not isinstance(value, classmethod)
]

顺便说一句,您的代码可以通过删除重复项和所有内容来简化为

import inspect

def get_fields(cls):
    seen = set()
    for cls in inspect.getmro(cls)[::-1]:
        if cls is object:
            continue
        attr_names = {
            name
            for name in cls.__dict__
            if name not in seen and not name.startswith("_")
        }
        seen.update(attr_names)
        yield (cls.__name__, sorted(attr_names))