简体   繁体   中英

Python Functions - how can I dynamically call a function when I don't know how many arguments it expects?

I'd like to write a method in python which dynamically reads a module and creates a list of all the functions in that module. Then I'd like to loop through this list and call each function. So far I have the following code:

import mymodule
from inspect import getmembers, isfunction

def call_the_functions():
    functions_list = [f for f in getmembers(mymodule) if isfunction(f[1])]
    for f in functions_list:
        result = f()

My problem is that my program is crashing because some of the functions require arguments. I'd like to do something like the following, but don't know how:

for f in functions_list:
    args = [""] * f.expectedNumberOfArguments()
    result = f(*args)

Am I going about this the right way? (I'm basically writing a unit test, and the first check is simply that the functions return an object of the right type, regardless of the arguments they are called with.)

You could use inspect.getargspec() :

In [17]: def f(x, z=2, *args, **kwargs): pass

In [18]: inspect.getargspec(f)
Out[18]: ArgSpec(args=['x', 'z'], varargs='args', keywords='kwargs', defaults=(2,))

Whether it's meaningful to call functions that you know nothing about with arbitrary arguments is a different question...

Your approach is fundamentally flawed. If written carefully, the functions will reject arguments of invalid type by raising TypeError or asserting. Failing that, they will try to access an attribute or method on the parameter and promptly get an AttributeError .

It is futile to try to avoid writing unit tests that know something about the functions being tested.

You can use the inspect module and getargspec . Here is a simple example:

import inspect

def myfunc(x): 
    return x * 2 

print inspect.getargspec(myfunc);

gives:

ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)

Some functions might be generators, so your test strategy of calling them might not give you what you expect, inspect.isgeneratorfunction() will allow you to test for that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM