0

I'm not sure if I'm using the correct terminology, but here's my code:

class Candidate(object):
        def __init__(self, party_code, state, age=random.randint(35, 70),
                social_index=(1 if party_code == 'dem' else -1 if party_code == 'rep' else 0),
                econ_index=(-1 if party_code == 'dem' else 1 if party_code == 'rep' else 0)):
            self.state = state
            self.party_code = party_code
            self.age = age
            self.social_index = social_index
            self.econ_index = econ_index

I would like to be able to use party_code to determine what the initial values of social_index and econ_index will be, but this isn't allowed with the way I currently have it set up. Is there an alternative way to dynamically set keyword variable on creation of this class?

Phil
  • 33
  • 4
  • 2
    the default value is determined at definition time (when the class block executes) not when the function is run, just put the code that determines their value in the function body. – Tadhg McDonald-Jensen Jun 29 '16 at 23:19
  • Note that that is the entire point of having an `__init__` method, to run some code to create the object. Your `age` will always default to the same number that was only generated once at definition time instead of once per instance. – Tadhg McDonald-Jensen Jun 29 '16 at 23:20
  • So you're saying if I instantiate the class 2 separate times, the age value will always be the same? Is there any way to get a random age each instantiation? – Phil Jun 30 '16 at 00:28
  • you will notice that in my answer `age` is defaulted to `None` and initialized as a random number in the function body. That is how you set a value every time the function is run, you do it in the function body. – Tadhg McDonald-Jensen Jun 30 '16 at 00:39

1 Answers1

0

Assuming you want social_index and econ_index to be parameters your code would look like:

class Candidate(object):
    def __init__(self, party_code, state, age=None,
            social_index=None, econ_index=None):
        if age is None:
            age=random.randint(35, 70)
        if social_index is None:
            social_index = (1 if party_code == 'dem' else -1 if party_code == 'rep' else 0)
        if econ_index is None:
            econ_index=(-1 if party_code == 'dem' else 1 if party_code == 'rep' else 0)
        self.state = state
        self.party_code = party_code
        self.age = age
        self.social_index = social_index
        self.econ_index = econ_index

You need to specify the logic to determine the values in the function body in order for it to be executed when the function is called. The default to the function is determined at definition (the def block) which is why the Mutable default trap exists.

On the other hand if you don't need to be able to pass them as arguments you can simplify it to this:

class Candidate(object):
    def __init__(self, party_code, state):
        self.state = state
        self.party_code = party_code
        self.age = random.randint(35, 70)
        if party_code == 'dem':
            self.social_index = 1
            self.econ_index = -1
        elif party_code == "rep":
            self.social_index = 0
            self.econ_index = 0
        else:
            self.social_index = 0
            self.econ_index = 0
Community
  • 1
  • 1
Tadhg McDonald-Jensen
  • 20,699
  • 5
  • 35
  • 59
  • I see, this seems to be a much better implementation of what I was trying to achieve. I do want **social_index** and **econ_index** to be optional arguments that will override any logic that would determine the default values so your first example is exactly what I was looking for. Thanks! – Phil Jun 30 '16 at 00:03