15

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).

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:

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):

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

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

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

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

2
  • 3
    I'm not sure exactly what you're trying to do with MyClass, but it sounds like you might invest in a collections.defaultdict(). See docs.python.org/library/…. Still interested in what other people have to say about modifying self.__dict__, rather than creating an instance variable that happens to be a dictionary. Commented Feb 9, 2012 at 3:01
  • 1
    @Noah Thanks Noah, I did not know the defaultdict class. It sounds really interesting! I'm now seeing I've certainly coded few "tools" for my code, that have been most probably created in some better coded python modules (eg. I've created a simple thing that seems to do a bit like the defaultdict, although much less complex). Thanks a lot. Commented Feb 9, 2012 at 5:35

2 Answers 2

27

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.

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

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:

class MyClass():
    def __init__(self):
        vars(self).update(a=dict(), b=dict(), c=dict())
Sign up to request clarification or add additional context in comments.

Comments

6

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?

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

setattr(self, _var, dict())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.