When defining a python class, how can I set a random variable in it?
Let's say I have a class called Person
which will only have the name and gender of the person.
Gender should be randomly selected from men and women. For this I will import a function random.randint()
. The random gender is determined by a random int.
import random
class Person:
alias = random.randint(1, 3)
if alias == 2:
gender = 'Male'
else:
gender = 'Female'
def __init__(self, name):
self.name = name
r = Person('rachel')
s = Person('Stanky')
print(r.gender)
print(s.gender)
However, the result I am getting for another person from this class is of the same gender. My understanding is a fixed value randint
. My question is how to make it different for each instance of the class.
source to share
The reason you never get a different gender is because the gender attribute is a class variable. When Python creates an object of a class Person
, the value is gender
never evaluated again. You need to make the variable gender
an instance attribute. This means that gender will be calculated on a per instance basis instead of class definition. eg:
import random
class Person:
def __init__(self, name):
self.name = name
alias= random.randint(1, 3)
if alias == 2:
self.gender = 'Male'
else:
self.gender = 'Female'
r= Person('rachel')
s= Person('Stanky')
print(r.gender)
print(s.gender)
What are the outputs
Female
Male
On the other hand, I think a much better choice for your task would be to use random.choice()
to choose a random gender from a list of genders (male or female):
from random import choice
class Person:
genders = ('Male', 'Female', 'Female')
def __init__(self, name):
self.name = name
self.gender = choice(Person.genders)
rachel = Person('Rachel')
stanky = Person('Stanky')
print(rachel.gender)
print(stanky.gender)
Note that in my example above Person.genders
, this is a class variable. This is on purpose. Since we only need to create the sex list once, we can make the list a class level variable.
source to share
You seem to have guessed correctly why gender does not change. To solve this problem, you can use property
for gender
:
import random
class Person(object):
def __init__(self, name):
self.name = name
@property
def gender(self):
try:
# If it has been defined for the instance, simply return the gender
return self._gender
except AttributeError:
# If it not defined yet, define it, and then return it
self._gender = random.choice(['male', 'female'])
return self._gender
r = Person('rachel')
s = Person('Stanky')
print(r.gender)
print(s.gender)
source to share
You have to put random generation by gender in __init__
so that it will be randomly generated for each instance of the class.
import random
class Person:
def __init__(self, name):
self.name = name
alias= random.randint(1, 3)
if alias == 2:
self.gender = 'Male'
else:
self.gender = 'Female'
r= Person('rachel')
s= Person('Stanky')
print(r.gender)
print(s.gender)
Three times:
$ python classRandom.py Male Female $ python classRandom.py Female Female $ python classRandom.py Female Male
source to share
The gender variable is currently a class variable, so it remains the same for the entire instantiated instance. You will need to change these to an instance attribute.
Side note: random.randint(1, 3)
either will return 1, 2, or 3 not just 1 or 2. This is not the same as indexing in which the ending is ignored. Right now, there is a higher chance of being a Woman, as it could be 1 or 3, so it random.randint(1,2)
makes more sense. I mentioned this just in case it wasn't done on purpose. You can also use random.choice
which will choose a random selection from the list.
import random
class Person:
def __init__(self, name):
self.name = name
self.gender= random.choice(["Male", "Female"]) # or random.choice(["Male", "Female", "Female"]) if you want a higher chance of being a female
r= Person('rachel')
s= Person('Stanky')
print(r.gender)
print(s.gender)
source to share