问个如何优雅初始化类的问题

2018-03-29 14:27:01 +08:00
 Tianny
Class A:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
A(a=1, b=2)

-----------------------分割线------------------

Class A:
    def __init__(self, a, b):
        self.a = a
        self.b = b
data = {'a':1, 'b':2}
A(**data)

第一种方式 __init__ 方法虽然很简单,不用写那么多参数,但是真正初始化实例的时候依然要按键值对方式传入,如果有十几个,就得诶个手写传入。

第二种方式,虽然真正初始化实例时传个字典就可以了,但是 __init__方法事先给定了属性名称,如果有很多,也要诶个写进去。

有没有两者兼得的方法呢?也就是

Class A:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

但是初始化的时候,可以不用诶个传属性-值进去。

讲的可能有点乱,不知道表达清楚没有

1820 次点击
所在节点    Python
8 条回复
justou
2018-03-29 15:19:25 +08:00
如果真的只有少量参数, 用第二种, 简单明了, IDE 里面的提示可以很清楚的看到有哪些参数要传, 最怕的是出现这种提示: func(*args, **kwargs), 丁点儿提示都没有呀! 除了翻文档还能干啥, 忘一次翻一次;

如果有大量参数, 怕是把一些相关的参数抽象到单独的类中更好哦(现在想想 matplotlib 的 api 用起来略烦人);

还有, "传个字典就可以了"这种想法要三思, 用在复杂系统中会直接导致程序逻辑不清晰, 重构困难(有时看到满屏的字典在飞就会想: 重构? 怕是重新撸一个更轻松哦), 稳健性超低, 改一个地方可能导致 N 个地方都要改, 字典当成纯粹的数据结构用就好了, OOP 还是多抽象跟封装.
jmc891205
2018-03-29 16:02:30 +08:00
第一种也可以传字典进去啊
qsnow6
2018-03-29 16:27:44 +08:00
第二种逻辑清晰,易于重构
balamiao
2018-03-29 16:54:09 +08:00
python 还需要这么麻烦,多参数?
xpresslink
2018-03-29 22:29:33 +08:00
没听说过大量参数还优雅一说,楼主确定是参数而不是数据?
fanhaipeng0403
2018-03-30 10:15:16 +08:00
attrs 库
nametuple
troywinter
2018-03-30 14:04:32 +08:00
如果你设计的类参数很多,那说明这个类设计的有问题,参考 clean architecture 前面几章。
Tianny
2018-03-30 15:13:02 +08:00
@troywinter 好的 谢谢~

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/442480

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX