在Python中创建对象时设置类属性的最佳方法是什么? [英] What is the best way to set the attributes of a class at object creation time in Python?

查看:186
本文介绍了在Python中创建对象时设置类属性的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我定义一个类时,我经常想在创建对象时为该类设置属性的集合.到目前为止,我已经通过将属性作为参数传递给 init 方法来做到这一点.但是,我对此类代码的重复性感到不满意:

When I define a class, I often want to set a collection of attributes for that class upon object creation. Until now, I have done so by passing the attributes as arguments to the init method. However, I have been unhappy with the repetitive nature of such code:

class Repository(OrderedDict,UserOwnedObject,Describable):
  def __init__(self,user,name,gitOriginURI=None,gitCommitHash=None,temporary=False,sourceDir=None):
    self.name = name
    self.gitOriginURI = gitOriginURI
    self.gitCommitHash = gitCommitHash
    self.temporary = temporary
    self.sourceDir = sourceDir
    ...

在此示例中,我必须键入name三次,gitOriginURI三次,gitCommitHash三次,temporary三次和sourceDir三次.仅设置这些属性.这是非常无聊的代码.

In this example, I have to type name three times, gitOriginURI three times, gitCommitHash three times, temporary three times, and sourceDir three times. Just to set these attributes. This is extremely boring code to write.

我已经考虑过按照以下方式更改此类:

I've considered changing classes like this to be along the lines of:

class Foo():
  def __init__(self):
    self.a = None
    self.b = None
    self.c = None

并初始化它们的对象,例如:

And initializing their objects like:

f = Foo()
f.a = whatever
f.b = something_else
f.c = cheese

但是从文档的角度来看,这似乎更糟,因为该类的用户然后需要知道需要设置哪些属性,而不是简单地为类的初始化程序查看自动生成的help()字符串.

But from a documentation standpoint, this seems worse, because the user of the class then needs to know which attributes need to be set, rather than simply looking at the autogenerated help() string for the class's initializer.

还有更好的方法吗?

我认为这可能是一个有趣的解决方案,那就是是否存在一个store_args_to_self()方法,该方法可以将传递给init的每个参数都存储为self的属性.是否存在这种方法?

One thing that I think might be an interesting solution, would be if there was a store_args_to_self() method which would store every argument passed to init as an attribute to self. Does such a method exist?

让我对此寻求更好方法感到悲观的一件事是,例如,在cPython的源代码中查看date对象的源代码,我看到了相同的重复代码:

One thing that makes me pessimistic about this quest for a better way, is that looking at the source code for the date object in cPython's source, for example, I see this same repetitive code:

def __new__(cls, year, month=None, day=None):
    ...
    self._year = year
    self._month = month
    self._day = day

https://github.com/python/cpython/blob/master/Lib/datetime.py#L705

urwid,尽管由于使用了setter而有些模糊,但它也具有这样的接受参数并将其设置为self的属性"的热土豆代码:

And urwid, though slightly obfuscated by the use of setters, also has such "take an argument and set it as an attribute to self" hot-potato code:

def __init__(self, caption=u"", edit_text=u"", multiline=False,
        align=LEFT, wrap=SPACE, allow_tab=False,
        edit_pos=None, layout=None, mask=None):
    ...

    self.__super.__init__("", align, wrap, layout)
    self.multiline = multiline
    self.allow_tab = allow_tab
    self._edit_pos = 0
    self.set_caption(caption)
    self.set_edit_text(edit_text)
    if edit_pos is None:
        edit_pos = len(edit_text)
    self.set_edit_pos(edit_pos)
    self.set_mask(mask)

https://github.com/urwid/urwid/blob/master/urwid/widget.py#L1158

推荐答案

您可以使用 dataclasses项目,以便为您生成__init__方法;还将进行表示,散列和相等性测试(以及可选的丰富比较和不变性):

You could use the dataclasses project to have it take care of generating the __init__ method for you; it'll also take care of a representation, hashing and equality testing (and optionally, rich comparisons and immutability):

from dataclasses import dataclass
from typing import Optional

@dataclass
class Repository(OrderedDict, UserOwnedObject, Describable):
    name: str
    gitOriginURI: Optional[str] = None
    gitCommitHash: Optional[str] = None
    temporary: bool = False
    sourceDir: Optional[str] = None

dataclasses是在 PEP 557-数据类 ,已被包含在Python 3.7中.该库将在Python 3.6及更高版本上运行(因为它依赖于3.6中引入的新变量注释语法).

dataclasses were defined in PEP 557 - Data Classes, which has been accepted for inclusion in Python 3.7. The library will work on Python 3.6 and up (as it relies on the new variable annotation syntax introduced in 3.6).

该项目的灵感来自 attrs项目,该项目仍提供了更多的灵活性和选项,以及与Python 2.7和Python 3.4及更高版本兼容.

The project was inspired by the attrs project, which offers some more flexibility and options still, as well as compatibility with Python 2.7 and Python 3.4 and up.

这篇关于在Python中创建对象时设置类属性的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆