Class variable losing scope on assignment

2019-02-28 22:48发布

问题:

I have a question regarding class variable scope persistence on assignment.

I have a dictionary as a class variablle, and as soon as I assign another dictionary to the variable in an instance method, the scope seems to be lost and values are not persisted between instances anymore.

Here's the code snippet:

class MyBaseClass(object):
    my_class_dict = {}  

    def __init__(self):
        print "Keys length: ", len(self.my_class_dict)
        if not len(self.my_class_dict.keys()):
            print "Initializing my_class_dict."
            # VERION  1 
            # self.my_class_dict.update({1:2})
            # VERSION 2 
            # self.my_class_dict = {1:2}
            # VERSION 3             
            self.my_class_dict[1] = 2


class MyChildClass1(MyBaseClass):

    def __init__(self):
        super(MyChildClass1, self).__init__()


class MyChildClass2(MyBaseClass):

    def __init__(self):
        super(MyChildClass2, self).__init__()       

if __name__=='__main__':
    child_1 = MyChildClass1()
    child_2 = MyChildClass2()

    print child_1.my_class_dict
    print child_2.my_class_dict

And here are the results.

VERSION 1 (1 initialization, scope persisted)

Keys length:  0
Initializing my_class_dict.
Keys length:  1
{1: 2}
{1: 2}

VERSION 2 (2 initializations, scope lost)

Keys length:  0
Initializing my_class_dict.
Keys length:  0
Initializing my_class_dict.
{1: 2}
{1: 2}

VERSION 3 (1 initialization, scope persisted)

Keys length:  0
Initializing my_class_dict.
Keys length:  1
{1: 2}
{1: 2}

So it looks as though the scope is only lost on full object assignment. Why does this happen? What is the rationale for that?

回答1:

This is entirely expected. Scope is not "lost": by assigning to self.my_class_dict, you create a instance attribute, which shadows the class attribute with the same name. Instances always look up attributes on the instance before the class, so the newly-created variable will be found first.