Не меняется значение атрибута класса (Python)
Имеется класс, описывающий дом. В нем, помимо всего остального есть параметр загрязненности (грязь), который является целочисленным.
Имеется класс описывающий жену, который является наследным от класса описывающим человека. У класса жены есть метод, позволяющий убраться дома (-100 к значению атрибута грязи). И в теле кода есть условие, что при параметре грязи 100 и более, запускается метод уборки.
Но параметр не меняется, хотя метод исправно запускается (например уменьшение сытости в следствие уборки). Остальные методы и атрибуты работают и изменяются как задумано.
В чем проблема?
import random
class House:
money = 100
food = 50
cat_food = 30
dirt = 0
class Person:
def __init__(self, name, satiety=30, happiness=100):
self.name = name
self.satiety = satiety
self.happiness = happiness
def eat(self):
self.satiety += 30
House.food -= 30
print('{} ест.'.format(self.name))
def pet_cat(self):
self.happiness += 5
self.satiety -= 10
print('{} гладит кота.'.format(self.name))
class Cat(Person):
def eat(self):
self.satiety += 2 * 10
House.cat_food -= 10
print('{} ест из миски.'.format(self.name))
def rip_wallpaper(self):
House.dirt += 5
self.satiety -= 10
print('Кот дерёт обои.')
def sleep(self):
self.satiety -= 10
print('Кот спит.')
class Husband(Person):
def play(self):
self.satiety -= 10
self.happiness += 20
print('{} играет.'.format(self.name))
def work(self):
self.satiety -= 10
House.money += 150
print('{} работает.'.format(self.name))
class Wife(Person):
def buy_food(self):
self.satiety -= 10
House.food += 50
House.cat_food += 10
House.money -= 60
print('{} купила еды.'.format(self.name))
def buy_fur_coat(self):
self.happiness += 60
self.satiety -= 10
House.money -= 350
print('{} купила шубу!.'.format(self.name))
def clean_up(self):
self.satiety -= 10
House.dirt -= 100
print('{} убралась в доме.'.format(self.name))
home = House()
husband = Husband('Муж')
wife = Wife('Жена')
cat = Cat('Шерстяное чудище')
for day in range(365):
print('\nПрошел день {}\n'.format(day + 1))
print('{}, сытость - {}, счастье - {}'.format(husband.name, husband.satiety, husband.happiness))
print('{}, сытость - {}, счастье - {}'.format(wife.name, wife.satiety, wife.happiness))
print('Дом. {} денег, {} еды, {} кошачьего корма, {} грязи'.format(home.money, home.food, home.cat_food, home.dirt))
cat_choice = random.randint(1, 2)
if cat_choice == 1:
cat.sleep()
else:
cat.rip_wallpaper()
if home.money < 500:
husband.work()
else:
husband.play()
if home.food < 5 or home.cat_food < 5:
wife.buy_food()
else:
wife.pet_cat()
if husband.happiness < 40:
husband.play()
if wife.happiness < 50:
wife.pet_cat()
elif wife.happiness < 100 and home.money > 370:
wife.buy_fur_coat()
if wife.satiety < 30:
wife.eat()
if husband.satiety < 30:
husband.eat()
if cat.satiety < 15:
cat.eat()
if husband.satiety < 0:
print('{} умер от голода!'.format(husband.name))
break
elif wife.satiety < 0:
print('{} умерла от голода!'.format(wife.name))
break
elif cat.satiety < 0:
print('{} умер от голода!'.format(cat.name))
break
if home.dirt >= 50:
wife.clean_up()
if home.dirt > 90:
husband.happiness -= 10
wife.happiness -= 10
if husband.happiness < 10:
print('{} умер от депрессии!'.format(husband.name))
break
elif wife.happiness < 10:
print('{} умерла от депрессии!'.format(wife.name))
break
home.dirt += 5
Ответы (2 шт):
Попробуйте так:
import sys
import random
class House:
money = 100
food = 50
cat_food = 30
dirt = 0 # <---- грязь
original_stdout = sys.stdout #
save_file = open('q1452500.txt', 'w') #
sys.stdout = save_file #
class Person:
# def __init__(self, name, satiety=30, happiness=100):
# -------------------------> vvvvv <---------------------------------------
def __init__(self, name, house, satiety=30, happiness=100):
self.house = house # +++
self.name = name
self.satiety = satiety
self.happiness = happiness
def eat(self):
self.satiety += 30
# House.food -= 30
self.house.food -= 30 # +++
print('{} ест.'.format(self.name))
def pet_cat(self):
self.happiness += 5
self.satiety -= 10
print('{} гладит кота.'.format(self.name))
class Cat(Person):
def eat(self):
self.satiety += 2 * 10
# House.cat_food -= 10
self.house.cat_food -= 10
print('{} ест из миски.'.format(self.name))
def rip_wallpaper(self):
# House.dirt += 5
self.house.dirt += 5
self.satiety -= 10
print('Кот дерёт обои.')
def sleep(self):
self.satiety -= 10
print('Кот спит.')
class Husband(Person):
def play(self):
self.satiety -= 10
self.happiness += 20
print('{} играет.'.format(self.name))
def work(self):
self.satiety -= 10
# House.money += 150
self.house.money += 150
print('{} работает.'.format(self.name))
class Wife(Person):
def buy_food(self):
self.satiety -= 10
# House.food += 50
# House.cat_food += 10
# House.money -= 60
self.house.food += 50
self.house.cat_food += 10
self.house.money -= 60
print('{} купила еды.'.format(self.name))
def buy_fur_coat(self):
self.happiness += 60
self.satiety -= 10
# House.money -= 350
self.house.money -= 350
print('{} купила шубу!.'.format(self.name))
def clean_up(self):
self.satiety -= 10
# !!! ---------------> !!! <-----------------------------------------------------
# House.dirt -= 100
self.house.dirt -= 100
print('{} убралась в доме.'.format(self.name))
home = House()
# ---------------------> vvvv <--------------------------------------------------
husband = Husband('Муж', home) # !!! +++ home
wife = Wife('Жена', home) # !!! +++ home
cat = Cat('Шерстяное чудище', home) # !!! +++ home
for day in range(365):
print('\nПрошел день {}\n'.format(day + 1))
print('{}, сытость - {}, счастье - {}'.\
format(husband.name, husband.satiety, husband.happiness))
print('{}, сытость - {}, счастье - {}'.\
format(wife.name, wife.satiety, wife.happiness))
print('Дом. {} денег, {} еды, {} кошачьего корма, {} грязи'.\
format(home.money, home.food, home.cat_food, home.dirt))
cat_choice = random.randint(1, 2)
if cat_choice == 1:
cat.sleep()
else:
cat.rip_wallpaper()
if home.money < 500:
husband.work()
else:
husband.play()
if home.food < 5 or home.cat_food < 5:
wife.buy_food()
else:
wife.pet_cat()
if husband.happiness < 40:
husband.play()
if wife.happiness < 50:
wife.pet_cat()
elif wife.happiness < 100 and home.money > 370:
wife.buy_fur_coat()
if wife.satiety < 30:
wife.eat()
if husband.satiety < 30:
husband.eat()
if cat.satiety < 15:
cat.eat()
if husband.satiety < 0:
print('{} умер от голода!'.format(husband.name))
break
elif wife.satiety < 0:
print('{} умерла от голода!'.format(wife.name))
break
elif cat.satiety < 0:
print('{} умер от голода!'.format(cat.name))
break
# ??? ------------> ??? <----------------------------------------------------------
# if home.dirt >= 50:
if home.dirt >= 100:
wife.clean_up()
if home.dirt > 90:
husband.happiness -= 10
wife.happiness -= 10
if husband.happiness < 10:
print('{} умер от депрессии!'.format(husband.name))
break
elif wife.happiness < 10:
print('{} умерла от депрессии!'.format(wife.name))
break
home.dirt += 5
sys.stdout = home.original_stdout #
home.save_file.close() #
помогло, хотя непонятно почему, ведь остальные атрибуты работали как надо
На самом деле нет, у вас тут всё работает не "как надо", потому что вы не понимаете разницу между:
- переменными класса
- переменными экземпляра класса
House - это класс
home = House() - это экземпляр класса.
Первоначально home получает те же переменные, что и сам класс, но в дальнейшем они живут своей отдельной жизнью. Поэтому когда вы проверяете переменную (поле класса) House.<поле>, а затем меняете переменную home.<поле>, то вы обращаетесь к двум разным переменным. Тут возможны два решения этой проблемы:
- либо вы не создаёте экземпляров класса - у вас будет строго один дом
Houseи вы работаете с ним строго через название класса - либо вы создаёте экземпляры класса и работаете с ними, но тогда те объекты, которые с ними работают, должны как-то получить ссылку на экземпляр класса, например как в ответе S.Nick передачей этой ссылки в конструктор классов, которые будут им пользоваться, и это наиболее правильный способ, ну либо можно сделать передачу через параметр метода, которому нужна эта ссылка, например:
def clean_up(self, house):
^^^^^ передали ссылку на экземпляр класса
self.satiety -= 10
house.dirt -= 100
^^^^^ обратились к нему
print('{} убралась в доме.'.format(self.name))
