Переменная в экземпляре класса не принимает новое значение при назначении. - PullRequest
0 голосов
/ 29 августа 2018

Итак, я работаю над RPG для командной строки, чтобы заполнить время и растягивать мускулы Python, поскольку я не тренировался пару лет. Раньше я программировал действительно функциональным образом, но я стараюсь разобраться в объектно-ориентированном программировании.

За исключением преамбулы, у меня есть проблема, когда после создания экземпляра класса моя переменная класса больше не определяется. Я сделал 2 версии этого, которые я буду использовать для демонстрации, так как мне сложно сформулировать.

Ниже я создал класс "персонажа", который собирался использовать как основу для персонажей игрока и npcs. В первом проекте я обновлял этот класс, прежде чем осознал, что он будет влиять на подклассы, когда я действительно хотел использовать его как шаблон. В любом случае, этот конкретный блок кода работал; он добавляет значения двух словарей вместе, а затем присваивает их character.characterStats. Затем он печатает их в соответствии с displayStats().

from collections import Counter

class character:
    def __init__(self, *args, **kwargs):
        pass

    def __setattr__(self, name, value):
        pass

    characterRace = ''
    characterStats = {}
    charLocation = ''
    charName = ''

class race:
    def __init__(self):
        pass

    baseStatsDict = {
        'Strength' : 5,
        'Agility' : 5,
        'Toughness' : 5,
        'Intelligence' : 5 }

    humanStatsDict = {
        'Strength' : 1,
        'Agility' : 1,
        'Toughness' : 1,
        'Intelligence' : 1 }


def displayRace():
    print("Race: ", character.characterRace, "\n")

def displayStats():
    for stat, value in character.characterStats.items():
        print(stat, "=", value)
    print("\n")

def raceSelection():
    playerInput = input("I am a ")
    playerInput
    playerLower = playerInput.lower()

    while "human" not in playerLower:
        if "human" in playerLower:
            character.characterStats = dict(Counter(race.baseStatsDict)+Counter(race.humanStatsDict))
            character.characterRace = 'Human'
            break

        playerInput = input()
        playerInput
        playerLower = playerInput.lower()


playerChar = character()
raceSelection()
displayRace()
displayStats()

И это был вывод:

Race:  Human 

Strength = 6
Agility = 6
Toughness = 6
Intelligence = 6

Это, однако, новый код, когда я попытался привести его в порядок и превратить класс в шаблон, которым он должен был быть, и начал использовать экземпляр класса playerChar, который по какой-либо причине не может присвоить новое значение playerChar.characterStats. playerChar.displayStats() печатает переменные characterRace и characterStats как пустые, даже если они назначаются, когда игрок вводит значение human.

from collections import Counter

class character:
    characterRace = ''
    characterStats = {}

    def __init__(self):
        pass

    def displayRace(self):
        print("Race: ", self.characterRace, "\n")

    def displayStats(self):
        for stat, value in self.characterStats.items():
            print(stat, "=", value)
        print("\n")

class race:
    def __init__(self):
        pass

    baseStatsDict = {
        'Strength' : 5,
        'Agility' : 5,
        'Toughness' : 5,
        'Intelligence' : 5 }

    humanStatsDict = {
        'Strength' : 1,
        'Agility' : 1,
        'Toughness' : 1,
        'Intelligence' : 1 }

def raceSelection():
    playerInput = input("I am a ")
    playerInput
    playerLower = playerInput.lower()

    while "human" not in playerLower:
        if "human" in playerLower:
            playerChar.characterStats = dict(Counter(race.baseStatsDict)+Counter(race.humanStatsDict))
            playerChar.characterRace = 'Human'
            break

        playerInput = input()
        playerInput
        playerLower = playerInput.lower()

playerChar = character()
raceSelection()
playerChar.displayRace()
playerChar.displayStats()

Так что это выведет:

Race:
\n
\n
\n

Итак, я знаю, что он может извлекать из class race словарей и добавлять их содержимое вместе, как в предыдущем коде. Если я попытаюсь напечатать характеристики player.x, это не выдаст никаких ошибок, поэтому он признает, что они существуют. Если бы кто-нибудь мог объяснить мне, что происходит и почему в этой новой итерации, я был бы очень благодарен.

РЕДАКТИРОВАТЬ: Итак, мы с другом пытались передать класс в качестве аргумента raceSelection(), мы пытались печатать строку после каждого вызова / обновления переменной, и мы пытались ввести строку в переменную, распечатав его, затем переопределив переменную новой строкой.

Введите:

class character:
    charRace = ''
    charStats = {}
    charLocation = ''
    charName = ''
    charString = "Cole said define a string."

В пределах if операторов:

if "human" in playerLower:
    print("Oh, you're just a really ugly human.")
    playerChar.charStats = dict(Counter(race.baseStatsDict)+Counter(race.humanStatsDict))
    playerChar.charRace = 'Ugly Human'
    print("playerChar.charString = ", playerChar.charString)
    playerChar.charString = "Redefine."
    print("playerChar.charString = ", playerChar.charString)
    break

Выход:

Oh, you're just a really ugly human.
playerChar.charString =  Cole said define a string.
playerChar.charString =  Cole said define a string.
Race: 

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Итак, после попытки переместить переменные в __init__ и из *1001*, пытаясь setattr(), пытаясь передать какой-либо аргумент через класс, чтобы у него были некоторые данные, пытаясь запустить экземпляр класса через функция, ни одно из этих решений не сработало в конце.

Оказалось, что решением было создать подкласс character и манипулировать им. Я подумал, что это будет хорошо, так как персонаж игрока будет видоизменяться в течение всего игрового процесса и никогда не увидит своих подклассов.

0 голосов
/ 29 августа 2018

Это не должно быть character.characterStats.items(), а self.characterStats.items(). Аналогично для всех других значений, которые принадлежат единица, конкретный символ.

Использование имени класса присваивает значение, которое принадлежит классу, и является одинаковым для всех создаваемых вами объектов. Lookup экземпляр против атрибутов класса .

...