10

If I have the following class, what's the best way of getting the exact list of variables and methods, excluding those from the superclass?

class Foo(Bar):
  var1 = 3.14159265
  var2 = Baz()
  @property
  def var3(self):
      return 42
  def meth1(self, var):
      return var

I want the tuple ('var1','var2','var3','meth1') with minimum overhead. This is being run in a Django environment, which seems to be putting some of it's class instance variables in the read-only __dict__ variable; a feat which I can't find a way to replicate.

Here's what I'm seeing while playing with it, any suggestions beyond trimming out the __* from the dir() or manually listing them?

>>> a=Foo()
>>> a
<__main__.Foo instance at 0x7f48c1e835f0>
>>> dict(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence
>>> dir(a)
['__doc__', '__module__', 'meth1', 'var1', 'var2', 'var3']
>>> a.__dict__
{}
1

5 Answers 5

11

If the class and its superclasses are known, something like:

tuple(set(dir(Foo)) - set(dir(Bar)))

If you want it to be more generic, you can get a list of the base classes using something like

bases = Foo.mro()

...and then use that list to subtract out attributes from all the base classes.

Sign up to request clarification or add additional context in comments.

2 Comments

I'm going to use your technique in my project, as the base class is predictable. I'll also implement some caching routine and save it as a method variable, thanks for the set manipulation tip!
keep in mind that mro() only works for new-style classes ie. those subclassing from 'object'
7

In your example, a is an instance, its __dict__ will include all variables set in its __init__ function. To get all class variables, use a.__class__.__dict__

Comments

3

A third answer is the inspect module which does the same as above

Comments

1
def getVariablesClass(inst):
var = []
cls = inst.__class__
for v in cls.__dict__:
    if not callable(getattr(cls, v)):
        var.append(v)

return var

if you want exclude inline variables check names on the __ at the start and the end of variable

Comments

1

If you want to introspect your own classes, you can do it on class definition and cache it by the way:

class Bar:
    parent_prop = 0


class Foo(Bar):
    my_prop1 = 1
    my_prop2 = 2

    def method1(self):
        pass

    SYMBOLS = [k for k in locals().keys() if not k.startswith('_')]



if __name__ == '__main__':
    print(Foo.SYMBOLS)

Output:

['my_prop1', 'my_prop2', 'method1']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.