Programmatically determining amount of parameters a function requires - Python
我正在创建一个简单的命令行实用程序,并使用字典作为一种case语句,关键字链接到它们的相应函数。这些函数都有不同数量的参数,因此当前需要检查用户是否输入了每个函数所需的正确数量的参数。我将所需数量放入字典大小写语句中,格式为
这个当前的设置工作得非常好,但是我只是想知道是否有一种方法可以确定函数中所需的参数个数,我的google尝试到目前为止没有返回任何值,但是我看到args和kwargs是如何通过无限的参数来破坏这样的命令的。允许。
检查.getargspec():
Get the names and default values of a function’s arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). args is a list of the argument names (it may contain nested lists). varargs and varkw are the names of the * and ** arguments or None. defaults is a tuple of default argument values or None if there are no default arguments; if this tuple has n elements, they correspond to the last n elements listed in args.
号
一般来说,由于使用varargs和kwargs,您想要的是不可能的,但是EDOCX1(python 2.x)和EDOCX1(python 3.x)接近了。
python 2.x版本:
1
2
3
4
5
6
7
8>>> import inspect
>>> def add(a, b=0):
... return a + b
...
>>> inspect.getargspec(add)
(['a', 'b'], None, None, (0,))
>>> len(inspect.getargspec(add)[0])
2python 3.x版本:
1
2
3
4
5
6
7
8>>> import inspect
>>> def add(a, b=0):
... return a + b
...
>>> inspect.getfullargspec(add)
FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=(0,), kwonlyargs=[], kwonlydefaults=None, annotations={})
>>> len(inspect.getfullargspec(add).args)
2号
在python 3中,使用
(因为
已经回答了这个问题,但如果没有检查模块,您也可以使用
使每个命令都成为一个类,从定义命令的一般结构的抽象基派生而来。尽可能将命令属性的定义放入类变量中,方法在处理该数据的基类中定义。
用工厂类注册每个子类。这个工厂类通过实例化适当的命令子类来获取参数列表,并决定要执行哪个命令。
参数检查由命令子类本身处理,使用正确定义的常规方法构成命令基类。
这样,您就不需要重复地编写相同的代码,也不需要模拟switch语句。它还使得扩展和添加命令变得非常容易,因为您可以简单地添加和注册一个新类。没有其他可以改变的。
好问题。我刚遇到一个问题,我想写一个接受回调参数的函数。根据该回调的参数数量,需要以不同的方式调用它。
我从Gimel的回答开始,然后扩展到能够处理与
下面是检查函数是否只需要一个参数的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | def func_has_one_arg_only(func, typical_argument=None, ignore_varargs=False): """True if given func expects only one argument Example (testbench): assert not func_has_one_arg_only(dict.__getitem__), 'builtin 2 args' assert func_has_one_arg_only(lambda k: k), 'lambda 1 arg' assert not func_has_one_arg_only(lambda k,x: k), 'lambda 2 args' assert not func_has_one_arg_only(lambda *a: k), 'lambda *a' assert not func_has_one_arg_only(lambda **a: k), 'lambda **a' assert not func_has_one_arg_only(lambda k,**a: k), 'lambda k,**a' assert not func_has_one_arg_only(lambda k,*a: k), 'lambda k,*a' assert func_has_one_arg_only(lambda k: k, ignore_varargs=True), 'lambda 1 arg' assert not func_has_one_arg_only(lambda k,x: k, ignore_varargs=True), 'lambda 2 args' assert not func_has_one_arg_only(lambda *a: k, ignore_varargs=True), 'lambda *a' assert not func_has_one_arg_only(lambda **a: k, ignore_varargs=True), 'lambda **a' assert func_has_one_arg_only(lambda k,**a: k, ignore_varargs=True), 'lambda k,**a' assert func_has_one_arg_only(lambda k,*a: k, ignore_varargs=True), 'lambda k,*a' """ try: import inspect argspec = inspect.getargspec(func) except TypeError: # built-in c-code (e.g. dict.__getitem__) try: func(typical_argument) except TypeError: return False else: return True else: if not ignore_varargs: if argspec.varargs or argspec.keywords: return False if 1 == len(argspec.args): return True return False raise RuntimeError('This line should not be reached') |
您可以使用
这种方法的问题在于,
这不太好。但这可能有助于有相同问题的人,同时也会遇到这样一个事实: