Pythonic:在类的self.__init__函数中使用__dict__
在用 spyder 这个开发工具编写一个新类的时候,我用 pylint 来检查代码的结果,结果遇到了一些错误信息(不过代码运行得很好,没有出错)。
背景:在构造函数里,我想创建很多新的成员。通常这些成员不多,所以我用的是这样的写法:
class MyClass():
def __init__(self):
self.a = ...
self.b = ...
但如果成员很多(比如说有10个),而且它们都设置为同样的初始值(比如说都是 dict()),我就想尝试这样写:
class MyClass():
def __init__(self):
_vars = ["a", "b", "c", ...]
for _var in _vars:
self.__dict__[_var] = dict()
在类的后面,我用下面的方式来引用一个成员:
class MyClass():
def my_method(self):
print self.c
错误来自 pylint(在 spyder 中):
当我在这个文件上使用 pylint 时,收到了一个错误信息,内容是:
MyClass.my_method: 实例 'MyClass' 没有 'c' 这个成员。
不过,代码运行得很好,没有出错,也就是说我可以毫无问题地访问成员 'c'。
问题:这样写代码合适吗?还是说我应该避免用这种方法来初始化成员?
2 个回答
6
这样做确实没问题,但一般来说,不建议直接操作 __dict__
。比如说,如果你以后想为你的对象的某个属性设置一个自定义的赋值方法,那就麻烦了。
在你的例子中,你可以简单地把循环中的那一行替换成下面的代码:
setattr(self, _var, dict())
27
是的,直接更新实例字典是合理的。你也可以用 setattr 来更新变量。我见过这两种方法都在实际代码中使用过。
使用 setattr 的话,就不需要直接去修改实例字典了:
class MyClass():
def __init__(self):
for var in 'a', 'b', 'c':
setattr(self, var, dict())
不过,如果你直接更新实例字典,有几个可以考虑的改进。例如,使用 vars() 而不是 __dict__ 看起来会更好一些。此外,你还可以使用 dict.update 方法来传递关键字参数:
class MyClass():
def __init__(self):
vars(self).update(a=dict(), b=dict(), c=dict())