2

Good day!

I'm writing a little tool that builds a GUI for my data-aware app.

The basic idea is to get a module containing a model description (sqla/elixir entities) as an input, and to present the user with a list of available classes (inherited from Entity()) and their fields (inherited from Field()) from this module.

The pyclbr module is fine for getting classes and their methods, but it can't read other class-members. I know about __dict__ and inspect module, but the problem is they require instantiation of a class in question, and that is kind of wrong in this context. So, is there another way ?

I really don't want to parse modules as text. :)

Jonik
  • 80,077
  • 70
  • 264
  • 372
AlexVhr
  • 2,014
  • 1
  • 20
  • 30

1 Answers1

5

I'm not sure I know what you mean:

class a(object):
    b = 'a'
    c = 'd'

print dir(a)

prints

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'b', 'c']

You can use

print [i for i in dir(a) if not i.endswith('__')]

if you don't want to see the special methods.

You don't need to instantiate the class to see it's members. You won't see attributes added inside methods, but everything defined in the class definition or a metaclass' __new__ method will be there.

See my answer to inspect.getmembers() vs __dict__.items() vs dir() for more info on what exactly these different functions return.

Community
  • 1
  • 1
agf
  • 171,228
  • 44
  • 289
  • 238
  • In your example dir is called in a context of a module. It means I have to import the module first, right? – AlexVhr Aug 18 '11 at 13:42
  • Just use `mod = __import__('modname')` if you don't want it in the current context. Then you can use `dir(modname)` to get it's attributes, and then work from there. If the module runs code when imported that you don't want run, it should be in `if __name__ = '__main__'` or a `run()` function anyway. – agf Aug 18 '11 at 13:47
  • Thanks for the tips, I'll probably go this way. In my case there aren't any guarantees that source module will not contain any run-on-import code, but I guess I'll have to live with it. Thank you! – AlexVhr Aug 18 '11 at 13:55