Domanda

I have following two code samples

Example 1:

class MyClass(object):

    def __init__(self, key, value):
         self._dict = self._dict.update({key:value})

m = MyClass('ten',10)
print m._dict

Output:

AttributeError: 'MyClass' object has no attribute '_dict'

Example2:

class MyClass(object):
    _dict = {}
    def __init__(self, key, value):
        self._dict = self._dict.update({key:value})

m = MyClass('ten',10)
print m._dict

Output: None

I am quite surprised with above behavior

Why the example2 compiled successfully by just addition of _dict = {} line, and line present at class scope. also why None output? I believed class scope variables has no relation with instance variable (special with self)

Any Explaination?

È stato utile?

Soluzione 2

The None output is because dict.update returns None. It modifies the dictionary itself, but does not return anything. So you probably wanted self._dict.update({key:value}). However, self._dict doesn't exist at initialization. So it would make more sense to do self._dict = {key: value}. If you're trying to modify the object's internal dictionary, then you should do self.__dict__.update({key:value}). However, this is bad practice. A better idea would be to write setattr(self, key, value). The reason Example2 is working successfully is because if you try to do getattr(instance, thing) (which is what instance.thing does), and thing is not in instance.__dict__, then instance.__class__.__dict__ will be checked instead.

Altri suggerimenti

Your 'example 2' defines a single dictionary at the class level. All instances of the class will share that same dictionary, at least unless you reassign _dict on the instance.

See this question for a detailed explanation: Why do attribute references act like this with Python inheritance?

As for why you're getting None - the update method changes its dict in place, and returns None.

Because the _dict in Example 2 is a class variable so it's an attribute of MyClass where as the _dict in Example 1 is an instance variable so it's a instance attribute.

Example 1: you are trying to update an object that is yet to be created. therefore error.

Example 2: When working in the inner scope of the function, if you modify the variable it makes changes to the previously defined _dict. But if you assign the value, it makes a new variable with the same name in the inner scope.

This will work.

class MyClass(object):
    _dict = {}
    def __init__(self, key, value):
        self._dict.update({key:value})

This will not.

class MyClass(object):
    _dict = {}
    def __init__(self, key, value):
        self._dict = self._dict.update({key:value})

because you are doing an assigning operation. It makes a new variable. So no changes are made to the _dict in the outer scope. Your _dict in the outer scope is still empty and returns None.

self._dict does not yet exist, so the first version raises that exception. The second one actually falls through looking _dict up on the instance and instead updates the class attribute, then assigns the class-level dictionary to the instance-scope _dict attribute.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top