Python类的关键字参数

4

我正在编写一个关于某个内容的类,并且我总是遇到一些繁琐的构造方式。是否有一种简单的方式,可以设置类,以便构造函数中的所有参数都以它们自己的名称进行初始化,即fish = 0 -> self.fish = fish

class Example(object):
    def __init__(self, fish=0, birds=0, sheep=0):
        self.fish = fish
        self.birds = birds
        self.sheep = sheep

你为什么需要这样奇怪的预分配? - user2665694
那么,为什么不将所需的默认值作为构造函数中默认值规范的一部分进行设置呢? - user2665694
3
@user2799617 面向新用户-有时代码格式并不总是显而易见...包含一个链接肯定是有帮助的,例如:http://stackoverflow.com/help/formatting,这样他们就有资源可以尝试去做。 - Jon Clements
3个回答

4
简短回答:不需要。你可以在构造函数中进行懒加载,除非你需要立即使用或公开它(也就是说你无法控制访问)。但是,在Python中,你不需要声明数据字段,如果它们出现在代码的不同部分,将会变得更加困难。
更全面的答案:你可以通过`**kwargs`(它持有一个参数名称/值对的字典)来完成一些魔法操作,但这是高度不建议的,因为这使得记录更改几乎不可能,并且用户很难检查某个参数是否被接受。仅在可选的内部标志时使用它。当你需要传递20个或更多参数时,它可能很有用,但在这种情况下,我建议重新考虑设计并进行数据聚类。
如果你需要一个简单的键/值存储,请考虑使用内置的`dict`。

好的,那很遗憾。是的,我不想使用 **kwargs 因为这个原因。谢谢。 - Ashiataka
@JonClements,好的。不过,我还是想知道为什么有人给我点了踩。我没有看到任何明显的错误... - Stefano Sanfilippo
我猜是user2799617。由于我的声望等级,我不能点赞这条评论,所以我猜我也不能点踩。 - Ashiataka
不用担心,Ashiataka,我并不关心那个踩票本身。相反,我认为踩票的人应该留下评论,说明哪里出了问题,这样发帖者就可以修正(并从自己的错误中学习)。当然,除非答案完全错误或误导人。踩票是为了严重的错误、错误信息或错误答案,而不是针对不同意见的人。 - Stefano Sanfilippo

3

对于Python 3.7+,您可以尝试使用数据类与类型注释相结合的方法。

https://docs.python.org/3/library/dataclasses.html

导入模块并使用装饰器。 对您的变量进行类型注释,无需定义init方法,因为它将自动为您创建。

from dataclasses import dataclass

@dataclass
class Example:
    fish: int = 0
    birds: int = 0
    sheep: int = 0

3
您可以使用inspect模块:
import inspect

class Example(object):

    def __init__(self, fish=0, birds=0, sheep=0):
        frame = inspect.currentframe()
        args, _, _, values = inspect.getargvalues(frame)
        for i in args:
            setattr(self, i, values[i])

这个方法可以运行,但是相对于手动设置来说更加复杂。使用装饰器可以将其隐藏起来:

@set_attributes
def __init__(self, fish=0, birds=0, sheep=0):
    pass

但是定义set_attributes变得棘手了,因为装饰器会在混合中插入另一个堆栈帧,而我无法完全正确地理解细节。


1
这样做很糟糕,但因为回答了问题所以加一分。 - Erik Aronesty

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接