在运行时期间将类实例放在列表中

时间:2017-03-02 20:21:15

标签: arrays list python-3.x

我正在使用Python3。

  1. 我创建了一个名为Players()的类,它包含9个属性。例如,其中一个属性是Player.name
  2. 然后我创建了9个名为p1,p1 .... p9。
  3. 的类的实例
  4. 在运行期间,要求用户挑选玩家并将其放入名为.....阵容的列表中。这是我使用的代码:

      for i in range(0,9):
          name = input("Enter player....")     #user picks an instance of the Player class
          lineup.append(name)                    #this loops 9 times so all the instances are picked and placed in the lineup list
    
  5. 4.当我在屏幕上打印列表时,它显示为['p2','p4',...........,'p1']#或用户选择的任何顺序< / p>

    5如果我尝试从列表中调用其中一个实例及其属性,例如..... lineup [index] .name,我会收到错误消息   “str没有名为name的属性”

    1. 但是,如果我在运行时之前将列表定义为阵容= [p1,p3,.....等](在这种情况下用户别无选择).....阵容[索引] 。名称 工作正常。

    2. 我的问题是......我如何允许用户创建列表,使其看起来像...... [p1,p2,p3 ....]而不是['p1', 'P2',......

3 个答案:

答案 0 :(得分:0)

您的代码生成lineup作为值"p1""p2"的字符串列表...您需要以某种方式将他们输入的每个值与您的某个播放器变量相对应。一个简单的(这绝对不是最好的)方法是定义一个函数:

def str_to_player(player_name):
    if player_name == "p1":
        return p1
    if player_name == "p2":
        return p2
    ....

请注意,此函数相当慢,p1p2 ...都必须在函数范围内。看看你是否能找到一种更好的方法来将字符串与玩家名称对应!

答案 1 :(得分:0)

您希望使用收到的输入创建Player课程的实例,并将其添加到列表中。例如

# Simple Player class
class Player(object):
    def __init__(self, name):
        self._name = name

    def get_name(self):
        return self._name

    def __repr__(self):
        return 'Player: ' + self._name

# Prompt for player names and return a list of Player instances
def get_players():
    lineup = []
    for _ in range(9):
        name = input("Enter player ... ")
        player = Player(name)
        lineup.append(player)
    return lineup

def main():
    lineup = get_players()

    print(lineup)
    print("Your Player lineup is")
    for i, p in enumerate(lineup, 1):
        print('{0}. {1}'.format(i, p.get_name()))

    # Example: Prompt for position and output Player name at position
    while True:
        pos = input("Get player at position: ")
        if not pos: # enter empty line to quit
            break

        # get a Player instance from lineup list at index
        player_at = lineup[int(pos) - 1]
        print("Player at position {0} is {1}".format(pos, player_at.get_name()))

修改

我可能误解了用户输入名称的方式,认为它是任何名称'Bob'而不是某个键('p1', 'p2', ...),因此您可以创建一个字典来将键映射到您的播放器实例

player_map = {
    'p1': Player('player 1'),
    'p2': Player('player 2'),
    'p3': Player('player 3'),
    'p4': Player('player 4'),
    'p5': Player('player 5'),
    'p6': Player('player 6'),
    'p7': Player('player 7'),
    'p8': Player('player 8'),
    'p9': Player('player 9')
}

然后你可以获得每个玩家实例。

注意:没有为人为错误添加任何处理。例如无效密钥。

def get_players():
    lineup = []
    for _ in range(len(player_map)):
        name = input("Enter player ... ")
        lineup.append(player_map[name])
    return lineup

答案 2 :(得分:0)

您遇到的核心问题是像"p1"这样的字符串与名为p1的变量不同。有几种方法可以解决这个问题,以达到你想要的效果。

“最简单”的方法可能是使用eval根据用户提供的字符串查找变量。这个工作,但这是一个非常糟糕的主意,因为用户可以键入任何有效的Python表达式,它将在您的程序中运行。这意味着他们可以输入代码来删除硬盘,发送垃圾邮件,或做任何他们能想到的事情。如果您不信任您计划的所有用户(例如,如果可以通过互联网访问),请务必不要这样做!

另一种方法是仅在用户命名时创建类的实例。如果您实际上不需要提前设置播放器实例,这可能是一个非常简单的解决方案。在创建每个实例时,只需将用户的字符串作为参数传递给类的__init__方法。

第三种方法,也许是最好的方法,是使用字​​典从名称映射到实例,而不是使用一堆变量。变量名称旨在供程序员使用。它们通常不是应该向程序用户公开的数据。如果需要将名称与对象关联,请使用可在它们之间进行映射的数据结构。字典是一种自然的选择,因为它在可散列键(如字符串)和任意对象(如实例)之间进行映射。