0

The following topics have been checked in lieu of my problem below.

In Python, how do I check if an instance of my class exists?

Python check instances of classes

Bear with me as I am an absolute beginner in Python. I've just started tackling Classes and I decided that a simple family financials emulator is a good starting point for me. Below is my code:

class Family(object):

def __init__(self,name,role,pay,allowance):
    self.name = name
    self.role = role
    self.pay = pay
    self.allowance = allowance

def describe(self):
    print self.name + " is the " + self.role + " of the family. He brings home " + str(self.pay) + " in wages and has a personal allowance of " + str(self.allowance) + "."


class Parent(Family):

def gotRaise(self,percent):
    self.pay = self.pay * int(1 + percent)
    print self.name + " received a pay increase of " + str((100*percent)) + ("%. His new salary is ") + str(self.pay) + "."

def giveAllowance(self,val,target):
    if hasattr(target, Family):
        self.pay = self.pay - int(val)
        target.pay = target.pay + int(val)
        print self.name + " gave " + target.name + " an allowance of " + str(val) + "." + target.name + "'s new allowance is " + str(target.allowance) + "."
    else: print ""

class Child(Family):

def stealAllowance(self,val,target):
    self.allowance = self.allowance + int(val)
    target.allowance = target.allowance - int(val)

def spendAllowance(self,val):
    self.allowance = self.allowance - int(val)


monty = Parent("Monty","Dad",28000,2000)
monty.describe() # 'Monty is the Dad of the family. He brings home 28000 in wages and has a personal allowance of 2000.'
monty.giveAllowance(1000,jane) # Produces a "NameError: name 'jane' is not defined" error.

The point of issue is the giveAllowance() function. I have been trying to find a way to check if the target instance of Family exists and to return a transfer of value if it does and a normal string if it doesn't. However, hasattr(), try - except NameError, isinstance(), and even vars()[target] all fail to address the NameError above.

Am I missing something here that I should be doing with respect to classes, ie. an exception when checking for instances from inside another class, wrong syntax, etc? If at all possible, I want to keep away from dictionaries unless they are the last resort, as it seems that from one of the links above, it's the only way.

Thanks!

Community
  • 1
  • 1
WGS
  • 13,969
  • 4
  • 48
  • 51

2 Answers2

1

The NameError is raised before your giveAllowance function is even called. If you write something like giveAllowance(10, jane), the variable jane has to exist, as a precondition for anything else. You can't do anything with a variable that doesn't exist. You can't use it "provisionally" and check later if it exists.

Why do you want to be able to do this? Raising an error in this situation seems like what should happen. I would suggest you rethink your design. Even assuming you could achieve what you want in terms of checking if the instance exists, it doesn't make a whole lot of sense to have a giveAllowance function that just returns an empty string when you try to give an allowance to a nonexistent person. It might make more sense to have a dictionary representing the family, with a key for each family member's name (as a string). You could then use if person in familyDict to check if the person exists.

Incidentally, Family is probably not a good name for your class, since it doesn't represent a family, it represents a family member.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • I get it! So 'jane' is basically checked prior to giveAllowance, which is why NameError was raised despite the 'correct' ways of checking I've been applying. A dictionary seems like the probable way to go, indeed. And I'll take the suggestion about the 'Family' name to heart. I'll find a way to better the code above. Marked as answer. Thanks! – WGS Oct 01 '13 at 04:21
0

Throw away the classes and you wrote:

x = 28
print x    # prints 28
print y    # throws a name error, complete lack of surprise

You never defined jane so the interpreter told you that.

You say:

I have been trying to find a way to check if the target instance of Family exists and to return a transfer of value if it does and a normal string if it doesn't.

You're getting way ahead of yourself, don't be so tricky to start. If you want jane to be instantiated, instantiate her.

msw
  • 42,753
  • 9
  • 87
  • 112
  • Your example is a much needed eye-opener. Truly, I shouldn't rely on the 'inside' of the class. Basically, what I wanted was, when an existing instance of Family gives allowance to a non-existent instance--later on--an option is presented to the user if he wants to include this non-existent target to the Family class. I think I am approaching this the wrong way, indeed. I shall revise the code. Thanks for your help as well! – WGS Oct 01 '13 at 04:23