假设我在函数中有一个整数参数列表,我想为它们中的每一个添加1。有没有一种干净的方法,像这样的伪代码:
def foo(a, b, c):
for argument in arguments:
argument += 1
...
特别是,我想避免在代码中显式引用这些参数中的每一个,并且只是迭代所有参数。将函数参数更改为仅列表不是一种选择,因为a, b, c
在代码中具有特定含义。
答案 0 :(得分:3)
clean 这样做的方法可能是使用 iterable unpacking 和映射,例如:
def foo(a,b,c):
a,b,c = map(lambda x:x+1,(a,b,c))
# ...
或者四舍五入:
def foo(a,b,c):
a,b,c = map(round,(a,b,c))
# ...
由于这仍然是显式,并且还将参数保留在foo
的函数签名中。
您当然可以使用*args
和**kwargs
并操纵这些(直接),但这可能会导致丢失有关参数a
,b
和{的信息{1}}意思是(他们的语义)。
另一种方法是删除参数的语义,使用装饰器:
c
然后你可以将装饰器放在def apply_func_args(func):
def dec(f):
def g(*args,**kwargs):
return f(*map(func,args),**{k:func(v) for k,v in kwargs.items()})
g.__name__ = f.__name__
g.__doc__ = f.__doc__
return g
return dec
上,如:
foo
现在,如果您致电@apply_func_args(round)
def foo(a,b,c):
# ...
,foo(1.4,1.3,1.9)
将获得foo
。例如,如果您想要(a,b,c) == (1,1,2)
print
,a
和b
:
c
所以我们在这里定义了一种干净的方法,将函数(>>> def apply_func_args(func):
... def dec(f):
... def g(*args,**kwargs):
... return f(*map(func,args),**{k:func(v) for k,v in kwargs.items()})
... g.__name__ = f.__name__
... g.__doc__ = f.__doc__
... return g
... return dec
...
>>> @apply_func_args(round)
... def foo(a,b,c):
... print((a,b,c))
...
>>> foo(1.4,1.3,1.9)
(1, 1, 2)
>>> foo(1.4,2.5,c=0)
(1, 2, 0)
>>> foo(b=1.4,a=2.5,c=0)
(2, 1, 0)
)应用于所有命名和未命名的round
参数。因此,如果我们致电foo
,foo
将始终获得舍入值。
答案 1 :(得分:2)
foo
或
def foo(a, b, c):
return call_other(round(a),round(b),round(c))
我想如果我理解你要做的事情......(从阅读评论中)
答案 2 :(得分:0)
这是一个没有副作用的例子:
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
c = [9, 8, 7, 6]
def foo(*args):
modified = list()
for idx, arg in enumerate(args):
modified.append([x + 1 for x in arg])
print modified
# do something else
# In [17]: foo(a, b, c)
# [[2, 3, 4, 5], [6, 7, 8, 9], [10, 9, 8, 7]]
通过此实现,您可以根据需要输入任意数量的数组。