Python - 迭代传递给函数的参数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python - 迭代传递给函数的参数相关的知识,希望对你有一定的参考价值。
假设我有以下示例:
class foo:
...
def bar(self, w, x, y, z, ...):
self.w = w
self.x = x
self.y = y
self.z = z
...
我希望通过参数使用bar()
循环将setattr()
中的n个属性赋值行减少到一个赋值行集。为此目的,有没有一种好方法可以循环通过所述论点?
我希望保留已定义的参数名称,以便限制传递给函数的参数数量以及传递它们的顺序。我也明白functions can be handled like objects;那么有可能获得一个已定义参数的列表作为函数的属性并迭代它吗?
答案
使用locals()
,您可以获取所有参数(以及任何其他局部变量):
class foo:
def bar(self, w, x, y, z):
argdict = {arg: locals()[arg] for arg in ('w', 'x', 'y', 'z')}
for key, value in argdict.iteritems():
setattr(self, key, value)
...
可能更有效率地做到这一点,如果你更喜欢可读性的线条或者发现它更具可读性,你可以内联argdict。
另一答案
因此,您不必明确地使用以下参数命名:
class foo:
def __init__(self, w, x, y, z):
args = locals()# gets a dictionary of all local parameters
for argName in args:
if argName!='self':
setattr(self, argName, args[argName])
另一答案
__setattr__
属性一次只分配一个属性,如果要分配多个属性,可以在函数头中使用**kwargs
并限制参数个数,只需检查函数中kwargs
的长度即可。并逐个调用每个参数的__setattr__
。这个方法的一个很好的理由是,由于很多原因,基本上将属性分配给对象而不考虑任何东西不是正确和理想的工作。因此,您必须通过考虑所有必需条件一次分配一个属性。
您也可以通过更新实例字典手动执行此操作,但您也应该处理异常。
In [80]: class foo:
def bar(self, **kwargs):
if len(kwargs) != 4:
raise Exception("Please enter 4 keyword argument")
for k, v in kwargs.items():
foo.__setattr__(self, k, v)
....:
In [81]: f = foo()
In [82]: f.bar(w=1, x=2, y=3, z=4)
In [83]: f.w
Out[83]: 1
In [84]: f.bar(w=1, x=2, y=3, z=4, r=5)
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
<ipython-input-84-758f669d08e0> in <module>()
----> 1 f.bar(w=1, x=2, y=3, z=4, r=5)
<ipython-input-80-9e46a6a78787> in bar(self, **kwargs)
2 def bar(self, **kwargs):
3 if len(kwargs) != 4:
----> 4 raise Exception("Please enter 4 keyword argument")
5 for k, v in kwargs.items():
6 foo.__setattr__(self, k, v)
Exception: Please enter 4 keyword argument
通过使用__setatter__
,它将自动处理异常:
In [70]: f.bar(1, 2)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-70-07d1f3c9e27f> in <module>()
----> 1 f.bar(1, 2)
<ipython-input-65-1049e26120c1> in bar(self, *args)
2 def bar(self, *args):
3 for item in args:
----> 4 foo.__setattr__(self, item, item)
5
TypeError: attribute name must be string, not 'int'
以上是关于Python - 迭代传递给函数的参数的主要内容,如果未能解决你的问题,请参考以下文章
Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数