Lin
Lin

Reputation: 1203

Changing an instance variable when another has been changed

I wish to be able to change a variable inside a class (in this case greet), every time we have a variable change on class.

The snipped is this one:

class Greet(object):                                                                                        
    def __init__(self, name="", age="", job=""):
        self.name = name
        self.age = age
        self.job = job
        self.greet = "Hello"

        if self.name:
            self.greet = self.greet + " " + self.name 

        if self.age:
            self.greet = self.greet + ". Good to know that you is " + self.age + " years old"

        if self.job:
            self.greet = self.greet + ". I think being a " + self.job + " is amazing."

    def shout(self):
        print self.greet
        return True

g1 = Greet(name="John Doe", job="Programmer")

g2 = Greet(name="Janis Duh", age="34", job="Singer")
g2.name = "Janis Joplin"

g3 = Greet()
g3.name = "Smith"
g3.age = "22"
g3.job = "Designer"

print ("Name %s\nAge %s\nJob %s\nGreet %s\n" % ( g1.name, g1.age, g1.job, g1.greet))
g1.shout

print ("Name %s\nAge %s\nJob %s\nGreet %s\n" % ( g2.name, g2.age, g2.job, g2.greet))
g2.shout

print ("Name %s\nAge %s\nJob %s\nGreet %s\n" % ( g3.name, g3.age, g3.job, g3.greet))
g3.shout

And the output is:

Name John Doe
Age
Job Programmer
Greet Hello John Doe. I think being a Programmer is amazing.

Name Janis Joplin
Age 34
Job Singer
Greet Hello Janis Duh. Good to know that you is 34 years old. I think being a Singer is amazing.

Name Smith
Age 22 Job Designer
Greet Hello

In no case shout method prints the "greeting" correctly. Even in cases where self.greet is correctly set.

g1 object prints ok because I have declared the variables while creating the instance.

g2 Changes the variable name correctly but the greeting phrase still points to the old value, seems it was not updated.

g3 Even worse, likely by the same reason g2 hasn't updated the name correctly on greeting.

Directions will be welcome

(late editing)

Following Adam Smith, hints I rather tried to keep "greeting" as a instance property as in:

def greet(self):
    self.greeting = "Hello!"
    if self.name:
        self.greeting += " {0.name}."
    if self.age:                                                                                        
        self.greeting += " Good to know you are {0.age} years old."
    if self.job:
        self.greeting += " I think being a {0.job} is amazing."
    print(self.greeting.format(self))

...

g = Greeter(...)
g.greet()

Works, but

print g.greeting

Give me something like:

Hello! {0.name}. Good ...

Upvotes: 1

Views: 68

Answers (2)

mementum
mementum

Reputation: 3203

self.greet is being calculated during __init__ and is never recalculated again.

My best approach would be to make greet a property. As such you could still use the syntax you have

def __init__(self, name="", age="", job=""):
    self.name = name
    self.age = age
    self.job = job

@property
def greet(self):
    txt = 'Hello'
    if self.name:
        txt += " " + self.name

    if self.age:
        txt += ". Good to know that you is " + self.age + " years old"

    if self.job:
        txt += ". I think being a " + self.job + " is amazing."

    return txt

In this way the greet is recalculated every time when you get it.

Now executing your test code:

g1 = Greet(name="John Doe", job="Programmer")

g2 = Greet(name="Janis Duh", age="34", job="Singer")
g2.name = "Janis Joplin"

g3 = Greet()
g3.name = "Smith"
g3.age = "22"
g3.job = "Designer"
print ("Name %s\nAge %s\nJob %s\nGreet %s\n" % ( g1.name, g1.age, g1.job, g1.greet))
g1.shout()

print ("Name %s\nAge %s\nJob %s\nGreet %s\n" % ( g2.name, g2.age, g2.job, g2.greet))
g2.shout()

print ("Name %s\nAge %s\nJob %s\nGreet %s\n" % ( g3.name, g3.age, g3.job, g3.greet))
g3.shout()

Produces this output:

Name John Doe
Age
Job Programmer
Greet Hello John Doe. I think being a Programmer is amazing.

Hello John Doe. I think being a Programmer is amazing.
Name Janis Joplin
Age 34
Job Singer
Greet Hello Janis Joplin. Good to know that you is 34 years old. I think being a Singer is amazing.

Hello Janis Joplin. Good to know that you is 34 years old. I think being a Singer is amazing.
Name Smith
Age 22
Job Designer
Greet Hello Smith. Good to know that you is 22 years old. I think being a Designer is amazing.

Hello Smith. Good to know that you is 22 years old. I think being a Designer is amazing.

And the manual printing of the instance variables is the same as that of the greet when calling shout

Upvotes: 2

Adam Smith
Adam Smith

Reputation: 54173

Sounds like you need to generate this in a function so it's calculated every time you call it.

class Greeter(object):
    def init(self, ...):
        ...

    def greet(self):
        greeting = "Hello!"
        if self.name:
            greeting += " {0.name}."
        if self.age:
            greeting += " Good to know you are {0.age} years old."
        if self.job:
            greeting += " I think being a {0.job} is amazing."
        print(greeting.format(self))

Upvotes: 3

Related Questions