【问题标题】:saving constructor arguments automatically自动保存构造函数参数
【发布时间】:2013-03-18 18:24:23
【问题描述】:

通常,类的构造函数会接受它的参数并将它们保存在实例中。例如:

class Example(object):
    def __init__(self, title='',backtitle='', height=20, width=50):
        self.title = title
        self.backtitle = backtitle
        self.height = height
        self.width = width

这是重复的,所以我创建了一个辅助函数来自动执行此操作:

from inspect import getargspec
def save_args(values):
    for i in getargspec(values['self'].__init__).args[1:]:
        values['self'].__dict__[i] = values[i]

class Example(object):
    def __init__(self, title='',backtitle='', height=20, width=50):
        save_args(vars())

我的问题如下:

  • 这是否会在某些类或 agruments 中失败
  • 它是可移植的吗?它可以在 Jython 上运行吗?等等。它在 python 2.7 和 3.2 上对我有用
  • 有更简单的替代方案吗?
  • 是否有一个 python 包已经可以做到这一点?

【问题讨论】:

    标签: python constructor


    【解决方案1】:

    当你的班级使用__slots__ 时它会失败。你可以改用setattr()

    from inspect import getargspec
    def save_args(values):
        for i in getargspec(values['self'].__init__).args[1:]:
            setattr(values['self'], i, values[i])
    

    如果__init__ 的 arguments 关键字参数当然都是声明的插槽。

    否则这应该适用于任何 Python 实现。

    您可能对previous discussion of the topic 感兴趣,这引发了Python-ideas list thread

    【讨论】:

    • FGITW -- 这就是我尝试单独解决 OP 的每个问题时得到的结果,而实际上只有第一个问题很重要 :)
    • 在过去的 6 个月里,关于 python-ideas 的某个地方对此进行了讨论,其中(在每个人都决定不必向语言中添加任何内容之后)人们提出并争论了大约 300 种不同的实现。如果您真的关心这一点,那么值得搜索档案。 (IIRC,如果您不关心可移植性,有一个使用框架黑客的解决方案可以处理 getargspec 无法处理的一些情况……但我不记得是什么情况。)
    • 这也可以在一个包含现有 __init__ 的元类中巧妙地处理,尽管我还没有真正完全确定它是如何在我的脑海中工作的(主要是因为我非常缺乏经验使用元类)
    • @mgilson:在 __init__ 方法上加上 pass 主体的装饰器也可以。
    • 是的,这也是真的。我确实有一些装饰器的经验:)
    【解决方案2】:

    这需要您编写更多代码,默默地忽略 Example 构造函数的所有错误参数,并且不支持 Example 构造函数的位置参数,但避免使用 inspect

    def save_args(obj, defaults, kwargs):
        for k,v in defaults.iteritems():
            if k in kwargs: v = kwargs[k]
            setattr(obj, k, v)
    
    class Example(object):
        def __init__(self, **kwargs):
            defaults = { 'title': '',
                         'backtitle': '',
                         'height': 20,
                         'width': 50 }
            save_args(self, defaults, kwargs)
    

    【讨论】:

    • inspect 有什么问题?只要丑陋被充分隐藏,我看不出有什么问题:)
    • inspect 没什么问题,我只是想证明没有它也可以做到。
    猜你喜欢
    • 1970-01-01
    • 2015-05-26
    • 2018-01-29
    • 2016-09-02
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    相关资源
    最近更新 更多