Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class variable losing scope on assignment

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?

like image 375
haren Avatar asked Feb 06 '26 01:02

haren


1 Answers

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.

like image 115
Daniel Roseman Avatar answered Feb 08 '26 20:02

Daniel Roseman