11

I have this code:

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

I know the reason is that I'm only changing the value of self.a in the No class. Is there any way 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)?

4
  • you can write a setter method in the class , and call it from the other class Commented Apr 3, 2013 at 14:44
  • I tried that, it keeps calling back self.a=1 Commented Apr 3, 2013 at 14:47
  • 1
    Also see stackoverflow.com/questions/68645/… Commented Apr 3, 2013 at 14:54
  • 1
    @MichalČihař in particular this answer 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. Commented Nov 17, 2020 at 16:09

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

6 Comments

I was using it as an example for something else I was trying to do, thank you
Using class vars like this seems like code smell. Are you sure what you are doing can't be accomplished some other way?
@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, you can get a class variable through self, but you can't set it that way.
@BobStein Thanks for pointing out that distinction. still bugs me!
@SujayPhadke it's a recurring trauma for me too. Perennial Python pitfall: attempting to set a class property via self.
|
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

1 Comment

This is not a static variable, it's a class variable. If it changes, it changes for the class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.