Skip to content Skip to sidebar Skip to footer

Get Static Variable Value

I'm trying to create a static variable to be accessed through different classes, assigning value to it, and getting this value when needed. I did use this way in order to achieve t

Solution 1:

As I explained in my comment, the problem comes when you assign 5 to i by way of:

GetPartition.i = 5

With this line of code, you are overwriting the property, and "bypassing" the property setter. What I mean by that is: the property setter is not called when you call its attribute name from the class; it is only called when you call its attribute name from a class instance.

Since it has been overwritten, the property no longer exists at that point and all references to the i attribute, whether from class instances or from the class itself, are distinct. They will no longer retrieve the same object, but distinct objects.

You can confirm this problem by doing this:

gp = GetPartition()
print(GetPartition.i) # the property is returned
GetPartition.i = 5# here the property is overwrittenprint(GetPartition.i) # 5 ; the property is goneprint(gp.i) # 5 because gp instance doesn't have its own i
gp.i = 2# now gp does have its own iprint(gp.i) # 2print(GetPartition.i) # 5 ; i is not synced

As I said above, the property getters and setters (and descriptors in general) only work with instances of GetPartition, not the class itself. They can be forced to work with the class itself by creating a metaclass - which is the class of a class - for your class; this is considered "deep black magic" by many people, and I don't recommend going that route if you can avoid it.

I believe the below example is probably the simplest way to implement the behavior you want. This approach abandons the use of properties in favor of overriding the attribute getter and setter methods directly:

classExample():
    i = 1# this is a "static variable"
    j = 3# this is a regular class attribute#designate which of the class attributes are "static"
    statics = {'i'}
    def__getattribute__(self, attr):
        '''Overrides default attribute retrieval behavior.'''if attr in Example.statics:
            #use class version if attr is a static varreturngetattr(Example, attr)
        else:
            #default behavior if attr is not static varreturnsuper().__getattribute__(attr)
    def__setattr__(self, attr, value):
        '''Overrides default attribute setting behavior.'''if attr in Example.statics:
            #use class version if attr is a static varsetattr(Example, attr, value)
        else:
            #default behavior if attr is not static varsuper().__setattr__(attr, value)

#testingif __name__ == '__main__':
    print("\n\nBEGIN TESTING\n\n")

    e = Example()
    #confirm instance and class versions of i are the same
    test = "assert e.i is Example.i"exec(test)
    print(test)

    e.i = 5#confirm they remain the same after instance change
    test = "assert e.i is Example.i"exec(test)
    print(test)

    Example.i = 100#confirm they remain the same after class change
    test = "assert e.i is Example.i"exec(test)
    print(test)

    e.j = 12#confirm both versions of j are distinct
    test = "assert e.j is not Example.j"exec(test)
    print(test)

    print("\n\nTESTING COMPLETE\n\n")

If you are not familiar with __getattribute__ and __setattr__, I should let you know that overriding them is often quite perilous and can cause big problems (especially __getattribute__). You'll find many people simply say "don't do it; rethink your problem and find another solution". Doing the overrides correctly requires a deep understanding of a wide range python topics.

I do not claim to have this deep understanding (though I think I have a pretty good understanding), so I cannot be 100% certain that my overrides as given above will not lead to some other problem for you. I believe they are sound, but just be aware that these particular corners of python can be pretty tricky.

Post a Comment for "Get Static Variable Value"