给定以下函数:
def foo(a, b, c):
pass
如何获取传递的参数列表/元组/字典等,而无需自己构建结构?
具体而言,我正在寻找 Python 版本的 JavaScript 的
arguments
关键字或 PHP 的 func_get_args()
方法。我不想使用
*args
或 **kwargs
来解决问题;我需要在函数定义中指定参数名称(以确保它们被传递),但在函数内部,我希望以列表或字典形式处理它们。给定以下函数:
def foo(a, b, c):
pass
arguments
关键字或 PHP 的 func_get_args()
方法。*args
或 **kwargs
来解决问题;我需要在函数定义中指定参数名称(以确保它们被传递),但在函数内部,我希望以列表或字典形式处理它们。locals()
函数获取函数内的局部变量字典,像这样:def foo(a, b, c):
print locals()
>>> foo(1, 2, 3)
{'a': 1, 'c': 3, 'b': 2}
这种方法有点取巧,因为locals()
返回的是本地范围内的所有变量,而不仅仅是传递给函数的参数。因此,如果你不将其放在函数的最顶部调用,结果可能包含比你想要的更多信息:
def foo(a, b, c):
x = 4
y = 5
print locals()
>>> foo(1, 2, 3)
{'y': 5, 'x': 4, 'c': 3, 'b': 2, 'a': 1}
我更愿意在函数顶部构建一个字典或列表,其中包含你需要的变量,就像其他答案中建议的那样。在我看来,这更明确地传达了你代码的意图,以更清晰的方式进行交流。
locals()
,否则它将包含在函数内定义的所有变量。 - Phillip B Oldhamlocals()
返回的是局部变量的快照,而不是指向某个内置字典的指针。因此,如果稍后定义了变量或者在函数内更改了参数,那么locals()
所分配的内容将不会发生变化。这正是你想要的(在Python中)。 - Michael Scheperdef foo(*args, **kwargs)
如何获取 *args 的字典? - Dust break这里是一个函数,您可以调用它来获取当前函数的kwargs。或者,如果您想直接在自己的函数中使用这些行而不是调用get_kwargs()
,只需删除.f_back
import inspect
def get_kwargs():
frame = inspect.currentframe().f_back
keys, _, _, values = inspect.getargvalues(frame)
kwargs = {}
for key in keys:
if key != 'self':
kwargs[key] = values[key]
return kwargs
def test(x, y=100):
z = 7
print(get_kwargs())
test(5, 6)
# Output: {'x': 5, 'y': 6}
test(5)
# Output: {'x': 5, 'y': 100}
inspect.getargvalues
的第四个参数返回当前帧的locals()
。因此,有效地调用一个函数来获取其调用环境的帧以返回locals()
- 似乎有点迂回。另一方面,它允许您在函数中执行其他操作,例如排除某些参数。感谢您的提交! - John Haberstroh*args
或 **kwargs
,如果参数不符合预期,则引发异常。def check_arguments(function_name,args,arg_names):
missing_count = len(arg_names) - len(args)
if missing_count > 0:
if missing_count == 1:
raise TypeError(function_name+"() missing 1 required positionnal argument: "+repr(arg_names[-1]))
else:
raise TypeError(function_name+"() missing "+str(missing_count)+" required positionnal argument: "+", ".join([repr(name) for name in arg_names][-missing_count:-1])+ " and "+repr(arg_names[-1]))
something
的东西。def f(*args):
check_arguments("f",args,["a","b","c"])
#whatever you want
...
以下是来自一个重复(更早??)问题的被接受答案的翻译:https://dev59.com/8XRB5IYBdhLWcg3wl4AP#582206:
frame = inspect.currentframe()
args, _, _, values = inspect.getargvalues(frame)
class my_class():
compulsory_default_kwargs = {'p':20,'q':30,'r':40}
formal_args_names = ['var1','var2']
def __init__(self,*args,**kwargs):
for key , value in locals().items():
if((key == 'args')):
if(len(args) == len(my_class.formal_args_names)):
for key_name , arg_value in zip(my_class.formal_args_names,args):
setattr(self,key_name,arg_value)
else:
raise Exception ('Error - Number of formal arguments passed mismatched required {} whereas passed {}'.format(len(my_class.formal_args_names),len(args)))
elif((key == 'kwargs') & (len(kwargs)!=0)):
for kw_key , kw_value in kwargs.items():
if kw_key in my_class.compulsory_default_kwargs.keys():
setattr(self,kw_key,kw_value)
else:
raise Exception ('Invalid key-word argument passed {}'.format(kw_key))
#elif((key!='self') & (key!='kwargs') ):
# setattr(self,key,value)
for key , value in my_class.compulsory_default_kwargs.items():
if key not in kwargs.keys():
setattr(self,key,value)
this_value = 'Foo'
my_cl = my_class(3,this_value,p='B',r=10)
my_cl.__dict__
你在头部指定了参数吗?
为什么不直接在正文中使用相同的信息呢?
def foo(a, b, c):
params = [a, b, c]
我错过了什么?
arguments
жҲ–PHPзҡ„func_get_args()
дёҚжҳҜзұ»дјјзҡ„пјҢиҖҢжҲ‘жӯЈеңЁеҜ»жүҫиҝҷз§ҚеҠҹиғҪгҖӮ - Phillip B Oldhamlog_methods_arguments
示例可以使用*args,**kwargs
参数。OP说必须指定确切的参数。这种代码异味的动机不清楚。 - Oddthinkingargs = [a, b, c]您可以使用以下代码将它们轻松地创建为元组:
args = (a, b, c)
arguments
或PHP的 func_get_args()
不类似,这正是我所寻找的。 - Phillip B Oldham