Python - 迭代传递给函数的参数

问题描述 投票:5回答:3

假设我有以下示例:

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;那么有可能获得一个已定义参数的列表作为函数的属性并迭代它吗?

python arguments variable-assignment setattr
3个回答
1
投票

使用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。


0
投票

因此,您不必明确地使用以下参数命名:

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])

-1
投票

__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'
© www.soinside.com 2019 - 2024. All rights reserved.