Pythonic:在类的函数self .__ init__中使用__dict__

时间:2022-09-11 18:11:54

While coding a new class with the spyder IDE, and using pylint to check the final result, I've ran into error messages (but the code work as expected without error).

在使用spyder IDE编写新类并使用pylint检查最终结果时,我遇到了错误消息(但代码按预期工作而没有错误)。

Context: in the constructor function, I want to create new members (quite a lot). Usually, these are few enough so I use this coding:

上下文:在构造函数中,我想创建新成员(非常多)。通常,这些都很少,所以我使用这个编码:

class MyClass():
    def __init__(self):
        self.a = ...
        self.b = ...

But in a case of many members (let's say 10), with all set to the same initial value (let's say they are all dict()), I was tempted to do that:

但是在许多成员的情况下(比如10),所有设置为相同的初始值(假设它们都是dict()),我很想这样做:

class MyClass():
    def __init__(self):
        _vars = ["a", "b", "c", ...]
        for _var in _vars:
            self.__dict__[_var] = dict()

Further in the class, I was refering to a member using:

在课堂上,我正在引用一名成员:

class MyClass():
    def my_method(self):
        print self.c

Error with pylint (in spyder):

pylint出错(在spyder中):

When using pylint on this file, I've got an error message saying:

在此文件上使用pylint时,我收到一条错误消息:

MyClass.my_method: instance of 'MyClass' has no 'c'member.

MyClass.my_method:'MyClass'的实例没有'c'member。

However, the code runs just fine, without error, ie. I may access the member 'c' without any problem.

但是,代码运行得很好,没有错误,即。我可以毫无问题地访问会员'c'。

Question: is this a proper coding, or should I avoid such a method to initialize members?

问题:这是一个正确的编码,还是应该避免这种方法来初始化成员?

2 个解决方案

#1


16  

Yes, it is reasonable to update the instance dictionary directly. Alternatively, you can use setattr to update the variables. I've seen both approaches used in production code.

是的,直接更新实例字典是合理的。或者,您可以使用setattr更新变量。我已经看到了生产代码中使用的两种方法。

With setattr there is no need to touch the instance dictionary directly:

使用setattr,无需直接触摸实例字典:

class MyClass():
    def __init__(self):
        for var in 'a', 'b', 'c':
            setattr(self, var, dict())

But if you update the instance dictionary directly, there are couple possible improvements to consider. For example, using vars() instead of __dict__ is a bit nicer looking. Also, you can use the dict.update method with keyword arguments:

但是,如果直接更新实例字典,则需要考虑几种可能的改进。例如,使用vars()而不是__dict__看起来更好看。此外,您可以将dict.update方法与关键字参数一起使用:

class MyClass():
    def __init__(self):
        vars(self).update(a=dict(), b=dict(), c=dict())

#2


5  

It is indeed fine, but I it's generally recommended to avoid messing with __dict__ directly. What if, for example, you want to put a custom setter for an attribute of your object later down the road?

它确实很好,但我通常建议避免直接搞乱__dict__。例如,如果您希望稍后为您的对象的属性放置自定义setter,该怎么办?

In your example case, you could simply replace the line in your for loop with the following:

在您的示例中,您可以使用以下内容替换for循环中的行:

setattr(self, _var, dict())

#1


16  

Yes, it is reasonable to update the instance dictionary directly. Alternatively, you can use setattr to update the variables. I've seen both approaches used in production code.

是的,直接更新实例字典是合理的。或者,您可以使用setattr更新变量。我已经看到了生产代码中使用的两种方法。

With setattr there is no need to touch the instance dictionary directly:

使用setattr,无需直接触摸实例字典:

class MyClass():
    def __init__(self):
        for var in 'a', 'b', 'c':
            setattr(self, var, dict())

But if you update the instance dictionary directly, there are couple possible improvements to consider. For example, using vars() instead of __dict__ is a bit nicer looking. Also, you can use the dict.update method with keyword arguments:

但是,如果直接更新实例字典,则需要考虑几种可能的改进。例如,使用vars()而不是__dict__看起来更好看。此外,您可以将dict.update方法与关键字参数一起使用:

class MyClass():
    def __init__(self):
        vars(self).update(a=dict(), b=dict(), c=dict())

#2


5  

It is indeed fine, but I it's generally recommended to avoid messing with __dict__ directly. What if, for example, you want to put a custom setter for an attribute of your object later down the road?

它确实很好,但我通常建议避免直接搞乱__dict__。例如,如果您希望稍后为您的对象的属性放置自定义setter,该怎么办?

In your example case, you could simply replace the line in your for loop with the following:

在您的示例中,您可以使用以下内容替换for循环中的行:

setattr(self, _var, dict())