我不想使用* args或** kwargs,因为我无法更改函数声明。
例如:
def foo( a, b, c ) """Lets say values passed to a, b and c are 1,2 and 3 respectively"""
...
...
""" I would like to generate an object preferably a dictionary such as {'a':1, 'b':2, 'c':3} """
...
...
有人可以建议一种方法吗? 提前谢谢。
答案 0 :(得分:5)
如果你不能改变函数“声明”(为什么不呢?)但是你可以改变函数的内容,那么只需要根据需要创建字典:
def foo(a, b, c):
mydict = {'a': a, 'b': b, 'c': c}
如果这不起作用,我认为您需要更好地解释您想要的内容以及您的情况下的约束条件。
这也会在上面的情况下给出类似的结果(除了参数之外你没有显示任何局部变量),但要警告you should not try to modify locals():
def foo(a, b, c):
mydict = locals()
答案 1 :(得分:1)
@Rohit,当你说“功能声明”时,我们不明白你的意思。如果您的意思是您不想更改函数的API(调用该函数的文档化方式),可能是因为您现有的代码已经调用了现有函数,那么您仍然可以使用**kwargs
表示法,并且来电者永远不会知道:
def foo(a, b, c):
return a + b + c
def foo(**kwargs):
total = 0
for x in ("a", "b", "c"):
assert x in kwargs
total += kwargs[x]
return total
def bar():
foo(3, 5, 7)
bar()
无法判断它正在调用哪个版本的foo()
,并且无关紧要。
也许你正在寻找一个可以包裹现有函数对象的“包装器”,而不需要改变函数对象的实际源代码?
def make_wrapper(fn, *arg_names):
def wrapped_fn(*args):
mydict = dict(tup for tup in zip(arg_names, args))
print("TEST: mydict: %s" % str(mydict))
return fn(*args)
return wrapped_fn
def foo(a, b, c):
return a + b + c
foo = make_wrapper(foo, "a", "b", "c")
foo(3, 5, 7)
新的包装函数将参数收集到mydict
并在调用函数之前打印mydict
。
答案 2 :(得分:1)
通过努力搜索StackOverflow,我found out如何做到这一点。您使用inspect
模块。
import inspect
def make_wrapper(fn):
arg_names = inspect.getargspec(fn)[0]
def wrapped_fn(*args, **kwargs):
# mydict now gets all expected positional arguments:
mydict = dict(tup for tup in zip(arg_names, args))
# special name "__args" gets list of all positional arguments
mydict["__args"] = args
# mydict now updated with all keyword arguments
mydict.update(kwargs)
# mydict now has full information on all arguments of any sort
print("TEST: mydict: %s" % str(mydict))
return fn(*args, **kwargs)
return wrapped_fn
def foo(a, b, c, *args, **kwargs):
# a, b, and c must be set; extra, unexpected args will go in args list
return a + b + c
foo = make_wrapper(foo)
foo(3, 5, 7, 1, 2)
# prints: TEST: mydict: {'a': 3, 'c': 7, 'b': 5, '__args': (3, 5, 7, 1, 2)}
# returns: 15
你去了,你说的问题的完美解决方案。它是一个包装器,你不需要传入参数,它应该适用于任何函数。如果您需要它来处理类对象或其他内容,您可以阅读inspect
的文档,并了解如何执行此操作。
注意,当然顺序不会保留在词典中,因此您可能看不到我在测试时看到的确切顺序。但是相同的值应该在dict中。
答案 3 :(得分:0)
def foo(a, b, c):
args = {"a": a, "b": b, "c": c}