11

Okay, I'll try and be extremely clear this time.

class Yes:

    def __init__(self):
        self.a=1

    def yes(self):
        if self.a==1:
            print "Yes"
        else:
            print "No, but yes"

class No(Yes):

    def no(self):
        if self.a==1:
            print "No"
        else:
            print "Yes, but no"
        self.a-=1 #Note this line

Now, while running:

Yes().yes()
No().no()
Yes().yes()
No().no()

I want it to print out:

Yes
No
No, but yes
Yes, but no

It gives me:

Yes
No
Yes
No

Now, I know the reason why is because I'm only changing the value of Self.a in the No class(Remember that line?). I want to know if there is anyway to change it in the Yes class while still in the No class (like if there was something that I could plug in in place of the self.a-=1 that would work).

user2154113
  • 401
  • 1
  • 5
  • 12
  • you can write a setter method in the class , and call it from the other class – karthikr Apr 03 '13 at 14:44
  • I tried that, it keeps calling back self.a=1 – user2154113 Apr 03 '13 at 14:47
  • 1
    Also see http://stackoverflow.com/questions/68645/static-class-variables-in-python – Michal Čihař Apr 03 '13 at 14:54
  • 1
    @MichalČihař in particular [this answer](https://stackoverflow.com/a/69067/673991) gets to the heart of the problem here: **you cannot set a class variable through `self`**. You must use the _class name_ instead. The confusion comes from being able to _get_ a class variable through `self`. – Bob Stein Nov 17 '20 at 16:09

2 Answers2

20

I'm not sure what possible use you have for this, but...

You want to manipulate a class variable, but you keep addressing instance variables. If you want a class variable, use a class variable!

class Yes:
    a = 1 # initialize class var.
    def __init__(self):
        self.a = 1 # point of this is what?

    def yes(self):
        if Yes.a==1: # check class var
            print "Yes"
        else:
            print "No, but yes"

class No(Yes):

    def no(self):
        if Yes.a==1: # check class var
            print "No"
        else:
            print "Yes, but no"
        Yes.a-=1 # alter class var
Francis Avila
  • 30,535
  • 6
  • 55
  • 94
  • I was using it as an example for something else I was trying to do, thank you – user2154113 Apr 03 '13 at 14:59
  • 3
    Using class vars like this seems like code smell. Are you sure what you are doing can't be accomplished some other way? – Francis Avila Apr 03 '13 at 15:07
  • 1
    @FrancisAvila I think you were thrown off by his setting `a` in the constructor. He was merely trying to demonstrate a method changing the value of a class variable. The answer to that would have been `Yes.a = 1`. [Moral of the story](https://stackoverflow.com/a/69067/673991), you can get a class variable through self, but you can't set it that way. – Bob Stein Nov 17 '20 at 16:12
  • @BobStein Thanks for pointing out that distinction. still bugs me! – Sujay Phadke Jul 30 '21 at 09:53
  • @SujayPhadke it's a recurring trauma for me too. Perennial Python pitfall: attempting to **set a class property via `self`**. – Bob Stein Jul 30 '21 at 14:02
  • @BobStein Wonder why python allows it. Ambiguity is not Pythonic. – Sujay Phadke Jul 30 '21 at 14:30
2

It appears what you want to use is a static variable rather than an instance variable. A static variable is shared between all the instances of the class.

class Yes:
    a = 1
    def __init__(self):
        pass

    def yes(self):
        if Yes.a==1:
            print "Yes"
        else:
            print "No, but yes"

class No(Yes):

    def no(self):
        if Yes.a==1:
            print "No"
        else:
            print "Yes, but no"
        Yes.a-=1 #Note this line

Yes().yes()
No().no()
Yes().yes()
No().no()

Will output:

Yes
No
No, but yes
Yes, but no
Jesse Vogt
  • 15,601
  • 14
  • 56
  • 71
  • 1
    This is not a static variable, it's a class variable. If it changes, it changes for the class. – Mayou36 Jun 27 '21 at 18:43