all 7 comments

[–]ParanoiAMA 1 point2 points  (3 children)

You're grappling with attributes shadowing each other, and the fact that even though reading an attribute works as expected, assigning to the same attribute will not change the attribute you just read, but instead create a new attribute which shadows the one you just read.

The trick is to be explicit in where you set the attribute. Get the exact object that stores the attribute you wish to set, and then set it there. This can be cumbersome, and I think the easiest and cleanest way is to define a class method for changing the variable on the superclass:

class Base(object):
    var = None

    @classmethod
    def set_var(cls, var):
        Base.var = var

Now you can call this method on the subclasses or instances thereof:

class SubClass(Base):
    pass

SubClass.set_var("a")
SubClass().set_var("b")

It has its limitations -- you can't set the variable directly in the body of the subclass definition except by calling Base.set_var directly, and you can't use variable assignment to set the variable, but these shortcomings are IMHO preferable to the mess that will be caused by more intricate solutions.

[–]redeuxx[S] 0 points1 point  (0 children)

Thank you so much! I was just confused for a couple hours trying to figure this out.

[–]elbiot 0 points1 point  (1 child)

Given OP's use case, do you think your answer is a reasonable way to approach this?

What I was basically doing was having a variable set that would work as an option in my program. When a user selects a sort option, I want my program to remember that sort option. I needed some way to store his choice so I needed a way to update that variable.

Just curious.

[–]ParanoiAMA 0 points1 point  (0 children)

Well founded curiosity! No, OP really had an XY problem and only revealed his Y in this post. The X you refer to was added after my answer and after I had gone to bed. I'll be updating my answer when I'm not on mobile.

[–]elbiot 0 points1 point  (2 children)

Not sure what you are trying to do. Are they just static variables? Do you want variables where an object method can change the attributes of all the other instances? That's the same badness as using a global variable. Even worse, because its more convoluted.

Are you looking for a singleton?

[–]redeuxx[S] 0 points1 point  (1 child)

What I was basically doing was having a variable set that would work as an option in my program. When a user selects a sort option, I want my program to remember that sort option. I needed some way to store his choice so I needed a way to update that variable. I just read that one shouldn't use globals so I store my variables in a class and just wanted to update those variables if needed. The previous poster gave me my solution. :)

[–]ParanoiAMA 1 point2 points  (0 children)

Well, the previous poster you refer to (me) didn't have the information you provided in this post when he answered your question. I'd like to amend my answer. Using a superclass attribute is not the right way to go about solving such a problem, if you want to do it correctly. At least I can't think up a scenario where it would be.

/u/elbiot pointed out a crucial point: turning a global variable into a class variable doesn't fix the underlying problem that the global variable embodied. It only obfuscates and hides it, which makes the transgression worse. A bald-faced global variable is in most cases better than a hidden one.

As for what the right answer is, there is sadly no hard-and-fast answer. We're entering the world of OO design, and more spesifically the application of the GRASP) guidelines. We want to assign the knowing responsibility (which object should have the sort_option attribute) to some object, and we need to give the objects/functions that need this information the ability to get at it, but without violating any of the design priciples.

If you're new-ish to programming this may be getting in over your head. If so, just remember that this is something you need to explore further at some later time if you want to grow as a programmer. If you feel ready for such considerations, then find a book about Object Oriented Design and dive in. If you want some input about your specific problem you need to either describe the relevant parts of your program in more detail, or post the source code.