Как мне создать экземпляр класса, используя пользовательский ввод?

#python

#python

Вопрос:

Я создаю текстовую приключенческую игру на python. Как только игра начнется, я хотел бы создать экземпляр класса с именем «Character», который является объектом персонажа игрока. Я хотел бы, чтобы пользователь мог выбирать расу персонажа, которого он хочет играть. Пока у меня есть:

 class Race:
    def __init__(self, name, passive, hp):
        self.name = name
        self.passive = passive
        self.hp = hp
 

и

 class Lizard(Race):
    def __init__(self, name, passive, hp):
        super().__init__(name, passive, hp)
        self.name = 'Lizardman'
        self.passive = 'Regrowth'
        self.hp = 20

    def regrowth(self):
        if 0 < self.hp <= 18:
            self.hp  = 2
 

и

 def race_select():
    races = ['Lizard']

    while True:
        for i, j in enumerate(races):
            print(f"[{i   1}]", j)

        choice = int(input('Pick a race:'))

        if choice <= len(races):
            print('You are a ', races[choice - 1])
            return races[choice - 1]
        else:
            continue
 

Если я правильно понимаю, если бы я хотел, чтобы раса была ящерицей, мне все равно пришлось бы делать

 character = Lizard('Lizardman', 'Regrowth', 20)
 

Есть ли простой способ позволить пользователю выбрать расу и объект, который будет создан соответствующим образом? Спасибо

Комментарии:

1. Чтобы ответить на оба ваших вопроса, прямо сейчас это вроде как работает, но я должен настроить его так, чтобы он выводил правильные вещи, чтобы он работал только в том случае, если есть один выбор расы. Я просто немного сбит с толку, потому что мне было интересно, есть ли какой-нибудь способ сделать так, чтобы я мог просто сказать character = Lizard() без указания каких-либо параметров, потому что я уже дал параметры в коде класса Lizard (он же ‘Lizardman’, ‘Regrowth’, 20… кажется немного повторяющимся делать это дважды)

2. Что касается параметров, вы можете просто иметь пустое __init__ значение для Lizard и просто передать жестко закодированные «Lizardman», «Regrowth», 20, …. в super() .

Ответ №1:

Простым решением было бы сопоставить имя классу с помощью словаря. В качестве простого примера:

 race_map = {"lizard": Lizard,
            "human": Human}  # I'm adding a theoretical other class as an example

choice = input('Pick a race:')
race_initializer = race_map.get(choice, None)  # Get the chosen class, or None if input is bad
if race_initializer is None:
    # They entered bad input that doesn't correspond to a race
else:
    new_creature = race_initializer(their_name, their_passive, their_hp)
 

new_creature теперь это новый объект выбранного класса.

Возможно, вы захотите стандартизировать ввод, используя choice.lower() , чтобы гарантировать, что заглавные буквы не имеют значения, когда они вводят свой выбор.


Я изменил его, чтобы разрешить указывать расу по имени строки вместо числа. Если вам нужно число, вы можете сохранить свой список, но применить ту же идею. Что-то вроде:

 race_list = races = [('Lizard', Lizard), ('human', Human)]
choice = int(input('Pick a race:'))
try:
    race_initializer = race_list[choice][1]  # 1 because the class object is the second in the tuple
    new_creature = race_initializer(their_name, their_passive, their_hp) 
except IndexError:
    # Bad input
 

Я включил имя в race_list , чтобы вы могли перебирать список и распечатывать ассоциации index-> name для выбора пользователем.

Вы также можете захотеть использовать более надежную структуру, чем обычный кортеж, для хранения сопоставлений name-> initializer, но это хорошо работает в простых случаях.

Комментарии:

1. Потрясающее спасибо за прояснение этого. Просто чтобы убедиться, будет ли код, которым вы поделились, помещен внутрь функции? Можете ли вы создать экземпляр класса внутри функции, и вы можете возиться с ним вне этой функции?

2. @Schnibs Этот код определенно может быть внутри функции. Если вы хотите new_creature выйти за пределы функции, в которой он был создан, вы могли бы просто return использовать объект из функции или использовать функцию как метод класса «environment», в котором хранятся все объекты, используемые в игре, и append new_creature список существ, поддерживаемых классом. Это действительно зависит от того, как вы планируете структурировать вещи.