Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

working through "Learning Python: Powerful Object-Oriented Programming’

chapter 28 has you create a class that will list all instance attributes of an object.

then the book offers some ideas, such as listing all attributes up the inheritance tree. when doing so, i used the @classmethod decorator shown below – and was wondering if there’s a way to filter those types of methods out of my listing:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

"""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)

when i run this:

Python 3
x = GreatGrandChild()
print(x)

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

but howCanIFilterThisOneOut is a classmethod, not an instance method. so just wondering if it’s possible to differentiate.

thanks

sandbox to try it:
https://edube.org/sandbox/af4390bc-77aa-11ec-ab3f-0242157e55ca

>Solution :

isinstance(x, classmethod) does the trick.

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

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading