Передача переменных обратно в класс в Python
Я новичок, пожалуйста, потерпите меня. Ниже мой код:
class Player():
name = "UnknownName"
stren = 10
dex = 10
con = 10
intel = 10
wis = 10
cha = 10
def randAssign(self):
global stren, dex, con, intel, wis, cha
stat_List = [stren, dex, con, intel, wis, cha]
for stat in stat_List:
r_1 = random.randint(1,6)
r_2 = random.randint(1,6)
r_3 = random.randint(1,6)
r_4 = random.randint(1,6)
stat_Val = r_1 + r_2 + r_3 + r_4 - min(r_1, r_2, r_3, r_4)
stat = stat_Val
randAssign - это метод в Player(). Я пытаюсь установить статистику игрока случайным образом, и мне нужно переписать переменные класса в момент активации randAssign(). По той или иной причине использование global передает следующую ошибку:
NameError: name 'stren' is not defined.
Использование нелокального кода приводит к этой ошибке:
SyntaxError: no binding for nonlocal 'stren' found
Без глобального или нелокального, он просто не переписывает Player()'s
переменные. Я сделал дюжину итераций этого, от совершенно неправильного до "Я думал, что это будет работать, но это не так", и мне нужна помощь.
3 ответа
Подобное определение ваших переменных внутри вашего класса сделает все экземпляры вашего класса общими для этих переменных, что может привести к нестандартным ситуациям (особенно для изменяемых объектов). (обратитесь к документации по Python) Скорее всего, вы захотите использовать это:
class Player:
def __init__(self):
self.stren = 10
self.xcx = 10
etc.
def randAssign(self):
self.stren = randint(1,10)
...
Не совсем уверен, если вы знакомы с методами класса против экземпляра, но попробуйте это:
class Player():
name = "UnknownName"
stren = 10
dex = 10
con = 10
intel = 10
wis = 10
cha = 10
@classmethod
def randAssign(cls):
stat_List = [cls.stren,
cls.dex,
cls.con,
cls.intel,
cls.wis,
cls.cha]
for stat in stat_List:
r_1 = random.randint(1,6)
r_2 = random.randint(1,6)
r_3 = random.randint(1,6)
r_4 = random.randint(1,6)
stat_Val = r_1 + r_2 + r_3 + r_4 - min(r_1, r_2, r_3, r_4)
stat = stat_Val
Учитывая то, что выглядит, как вы делаете (создание случайной статистики игрока), это было бы более уместно, если бы это делалось для каждого экземпляра игрока под __init__
призывать к инстанции
Прочтите это ТАК для получения дополнительной информации о разнице между этими двумя методами.
Изменить: чтобы проиллюстрировать точку в комментариях...
Это проблема, с которой вы столкнетесь при использовании вашего метода (мой пример, приведенный выше, решает только вашу проблему с областью видимости, а не вашу реализацию)
class Temp:
stat = 1
@classmethod
def test(cls):
stats = [cls.stat] # container contains copies of primitive types
print (stats) # [1]
for i in range(1):
stats[i] = (stats[i] + 2) * 3 # 1 + 2 * 3 = 9
print (stats) # [9]
print (cls.stat) # 1
Чтобы сделать то, что комментарии появляются, вы хотите:
class Temp:
stats = {'stat': 1}
@classmethod
def test(cls):
stats = [cls.stats] # container contains reference to another container
print (stats) # {'stat': 1}
for stat in stats:
cls.stats[stat] = (cls.stats[stat] + 2) * 3 # 1 + 2 * 3 = 9
print (stats) # {'stat': 9}
print (cls.stats) # {'stat': 9}, look they updated!
Поскольку вы уже проходите self
аргумент в определении вашей функции, вы должны ссылаться на эти переменные в соответствующем пространстве имен:
self.stren = ...
вместо
globals stren
stren = ...