Luke Taylor
Luke Taylor

Reputation: 9571

Get number of args for function

I have a module, ui. I'd like to get a list of all the classes that ui defines which are a subclass of ui.View, and that can be called without arguments.

I've tried the following code:

ui_elements=[d for d in ui.__dict__.values() if type(d)==type and inspect.getargspec(d.__init__)[0]==1 and isinstance(d(),ui.View)]

But I get the following error from inside the inspect module:

TypeError: <slot wrapper '__init__' of 'object' objects> is not a Python function

I'm using inspect instead of a try: except: just because checking beforehand seems like a better solution than trying it to see if it works.

So, how can I get a list of all the classes that subclass ui.View and do not require arguments to create? I'd like to do this inline if possible, and I'd also like to avoid using try:/except: statements.

Upvotes: 1

Views: 140

Answers (2)

Guillaume
Guillaume

Reputation: 10971

As said in comments, you should use try/catch, but if you really want to do it that way...

First, use inspect to check if your symbol is a class, use issubclass as suggested in comments and you want the number of arguments to be 1, not the first argument to be 1. So, something like this:

ui_elements = [ d for d in ui.__dict__.values()
    if (inspect.isclass(d) and
        issubclass(d, ui.View) and
        inspect.ismethod(d.__init__) and
        len(inspect.getargspec(d.__init__)[0]) == 1) ]

Upvotes: 1

Alfe
Alfe

Reputation: 59516

To get a list comprehension with try/except you can use a local function:

def tryCreate(class_):
  try:
    return class_()
  except:
    return None

ui_elements = set(tryCreate(d) for d in ui.__dict__.values()
    if issubclass(d, ui.View)) - set(None)

Okay, it's a set comprehension in the end ;-)

Upvotes: 1

Related Questions