Python:如何轻松将函数参数复制到对象的字段中?

4 投票
7 回答
5458 浏览
提问于 2025-04-15 23:11

很多时候,我有一些成员函数,它们的作用是把参数复制到对象的字段里。比如:

class NouveauRiches(object):
  def __init__(self, car, mansion, jet, bling):
    self.car = car
    self.mansion = mansion
    self.jet = jet
    self.bling = bling

有没有什么Python的语法可以让上面的代码写起来不那么繁琐呢?可以使用 *args:

def __init__(self, *args):
  self.car, self.mansion, self.jet, self.bling = args

优点:写起来不那么繁琐

缺点:函数的签名不够清晰,调用这个函数的时候需要去看函数的代码才能知道怎么用

缺点:如果传入的参数数量不对,不会抛出 TypeError 错误(但会抛出 ValueError

还有其他的建议吗?(无论你的建议是什么,确保调用这个函数的代码保持简单)

7 个回答

1

我不太确定这个主意是否好,但确实可以这样做:

import inspect
class NouveauRiches(object):
    def __init__(self, car, mansion, jet, bling):
        arguments = inspect.getargvalues(frame)[0]
        values = inspect.getargvalues(frame)[3];
        for name in arguments:
            self.__dict__[name] = values[name]

不过,这样写起来也不是很好看,不过我想你可以把它放在一个可以重复使用的工具方法里。

2

我会选择这个方法,另外你也可以覆盖已经定义的属性。

class D:
  def __init__(self, **kwargs):
    self.__dict__.update(kwargs)

不过我个人还是会选择走比较长的路。想想这些:

- Explicit is better than implicit.
- Flat is better than nested.
(The Zen of Python)
2

你可以通过一个辅助方法来实现这个功能,类似下面这样:

import inspect

def setargs(func):
    f = inspect.currentframe(1)
    argspec = inspect.getargspec(func)
    for arg in argspec.args:
        setattr(f.f_locals["self"], arg, f.f_locals[arg])

使用方法:

class Foo(object):

    def __init__(self, bar, baz=4711):
        setargs(self.__init__)

        print self.bar # Now defined
        print self.baz # Now defined

这个写法看起来不太美观,可能只适合在做原型时使用。如果你打算让别人看这个代码,最好还是用明确的赋值方式。

其实可以改进一下,让它不需要把函数作为参数传入,但那样会需要更多复杂的技巧和小把戏 :)

撰写回答