【问题标题】:Is there a Python shortcut for an __init__ that simply sets properties? [duplicate]是否有用于简单设置属性的 __init__ 的 Python 快捷方式? [复制]
【发布时间】:2017-03-25 13:30:10
【问题描述】:

在 Python 中有时会看到这样的 __init__ 代码:

class SomeClass(object):
    def __init__(self, a, b, c, d, e, f, g):
        self.a = a
        self.b = b
        self.c = c
        self.d = d
        self.e = e
        self.f = f
        self.g = g

特别是如果所讨论的类纯粹是一个没有行为的数据结构。是否有(Python 2.7)快捷方式或制作方法?

【问题讨论】:

  • 如果您的班级没有任何行为,您可以改用namedtuple
  • @PeterWood 是的,这很适合我的目的。您可以将其发布为答案,以便我接受。
  • 您可以发布您自己问题的答案(c:。让它变得更好,它会被点赞,您甚至可以接受它。我并不总是有时间写不错的答案,但喜欢轻轻地将人们推向正确的方向。
  • @PeterWood 会做,只是想知道。

标签: python python-2.7 class shortcut


【解决方案1】:

您可以使用 Alex Martelli 的 Bunch recipe

class Bunch(object):
    """
    foo=Bunch(a=1,b=2)
    """
    def __init__(self, **kwds):
        self.__dict__.update(kwds)

【讨论】:

  • 这样做的问题是无法控制存在哪些属性。但这是一个很好的通用解决方案。
  • 作为Peter Wood suggests,如果您想要固定数量的命名属性,请改用namedtuple
  • 这也不支持位置参数。
【解决方案2】:

您可能会发现 attrs 库很有帮助。下面是来自文档overview page 的示例:

>>> import attr
>>> @attr.s
... class SomeClass(object):
...     a_number = attr.ib(default=42)
...     list_of_numbers = attr.ib(factory=list)
...
...     def hard_math(self, another_number):
...         return self.a_number + sum(self.list_of_numbers) * another_number
>>> sc = SomeClass(1, [1, 2, 3])
>>> sc
SomeClass(a_number=1, list_of_numbers=[1, 2, 3])
>>> sc.hard_math(3)
19

如果您使用的是 Python 3.8+,则可以使用 dataclasses

>>> from typing import List
>>> from dataclasses import dataclass, field
>>> @dataclass
... class OtherClass:
...     a_number: int=42
...     list_of_numbers: List[int] = field(default_factory=list)
...     def hard_math(self, another_number):
...         return self.a_number + sum(self.list_of_numbers) * another_number
>>> OtherClass=SomeClass
>>> oc = OtherClass(1, [1, 2, 3])
>>> oc
SomeClass(a_number=1, list_of_numbers=[1, 2, 3])
>>> oc.hard_math(3)
19

【讨论】:

  • 我很高兴他们至少有 s() 和 ib() 的“严肃的商业别名”。
【解决方案3】:

当然。

Class SomeClass(object):
    def __init__(self, **args):
        for(k, v) in args.items():
            setattr(self, k, v)

还有v = SomeClass(a=1, b=2, c=3, d=4)

这会让你的代码难以理解。

祝你好运。

【讨论】:

  • 这可以防止轻松设置默认值,不是吗?您必须在 self.some_value = 123 这样的函数中对它们进行硬编码,这违背了拥有一个简短的构造函数的全部目的。
【解决方案4】:

您可以使用__new__ 方法创建一个类,该方法将任何类属性复制到对象,然后从中继承。

http://www.oreilly.com/programming/free/how-to-make-mistakes-in-python.csp 举例说明了为什么我刚才所说的是一个应该避免的糟糕想法。

(简短版:它不适用于可变对象,并且处理这些问题的变通办法不值得。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-12
    • 2014-06-04
    • 2017-06-05
    • 1970-01-01
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多