【问题标题】:How do I iterate over object properties and assign user input to them?如何迭代对象属性并将用户输入分配给它们?
【发布时间】:2019-08-08 15:38:44
【问题描述】:

我正在通过编写 DnD 风格的 roguelike/地牢爬行游戏自学 Python。我的角色创建和游戏玩法基于 5E SRD。

我已经完成了 Roguebasin TCOD 教程和 Philip Johnson 的文字冒险教程。

我要做的是从输入中获取一个值并将其分配给适当的统计数据,我已将其定义为角色对象的属性。

class BaseCharacter:
    def __init__(self):        
        self.strength = None
        self.dexterity = None
        self.constitution = None
        self.intelligence = None
        self.wisdom = None


            print("With the standard array, you get these scores to distribute as you see fit: ")
            print("15, 14, 13, 12, 10, 8")
            values = [15, 14, 13, 12, 10, 8]
            stats = ["strength", "dexterity", "constitution", "intelligence", 
             "wisdom", "charisma"]
               ordered_values = []
            for s in stats:
                print("Which score would you like to assign to {}?"                     
                   .format(s))
                value = input()
                ordered_values.append(value)
                values.remove(int(value))
                print("Remaining values: " + str(list(values)))

我有一些这样的东西,以便我的代码编译并运行以进行测试。我想遍历统计信息列表并将用户输入分配给相应的统计信息:

Which score would you like to assign to strength?
15
Remaining values: 14, 13, 12, 10, 8

print(self.strength)
15

这似乎是可行的,但到目前为止,我想出的只是将统计信息和输入压缩到元组中。我对如何真正确保将正确的值分配给正确的属性持空白。

【问题讨论】:

  • 你知道你可以将这些值传递给你的类的构造函数吗?
  • 但这不会破坏循环的目的吗?我最初有self.s = value,认为会使用s 的当前值。但是 Python 似乎将其解释为我试图将 self.s 分配为新属性并给出未解决的名称错误。
  • 没关系。我没有进一步阅读。 :)

标签: python loops properties


【解决方案1】:

读取__init__ 之外的值,并将它们作为参数传递给实例化角色时。如果您想将交互式会话与实例化一起包装在单个函数中,请将其设为类方法。

import random


class BaseCharacter:
    stats = ["strength", "dexterity", "constitution", "intelligence", "wisdom", "charisma"]
    def __init__(self, s, d, co, i, w, ch):        
        self.strength = s
        self.dexterity = d
        self.constitution = co
        self.intelligence = i
        self.wisdom = w
        self.charisma = ch

    @classmethod
    def create(cls):
        print("With the standard array, you get these scores to distribute as you see fit: ")
        values = [15, 14, 13, 12, 10, 8]
        print(values)
        ordered_values = []
        for s in self.stats:
            print("Which score would you like to assign to {}?".format(s))
            value = input()
            ordered_values.append(value)
            values.remove(int(value))
            print("Remaining values: " + str(list(values)))

        return cls(*ordered_values)

    # To demonstrate the benefit of separating the source of the
    # attributes from the actual instantiation
    @classmethod
    def random(cls):
        # Simulate 3d6 for each of the 6 stats
        random_stats = [sum(random.randint(1,6) for _ in range(3))
                         for _ in self.stats]
        return cls(*random_stats)

new_character = BaseCharacter.create()

【讨论】:

  • 其实,忽略我的回答,有一个更简单的解决方案。在类的__init__ 函数中,将self.constitution 分配给c,但在参数列表中,它是co
  • 糟糕,谢谢,在添加缺少的魅力参数后忘记更新了。
【解决方案2】:

我会按照这些思路做一些事情。在构造函数中提供实例的值。为了获得这些值,我会反复要求输入并将名称映射到值。 __repr__ 方法只是为了漂亮的打印。稍后在显示统计信息时可能会派上用场。

class Dude:
    def __init__(self, strength, dexterity, constitution, ingelligence, wisdom, charisma):
        self.strength = strength
        self.dexterity = dexterity
        self.constitution = constitution
        self.ingelligence = ingelligence
        self.wisdom = wisdom
        self.charisma = charisma

    def __repr__(self):
        return f"""Dude:
STR: {self.strength}
DEX: {self.dexterity}
CONST: {self.constitution}
INT: {self.ingelligence}
WISD: {self.wisdom}
CHAR: {self.charisma}
"""


values = [15, 14, 13, 12, 10, 8]
stats = ['strength', 'dexterity', 'constitution', 'ingelligence', 'wisdom', 'charisma']

assigned = {}
for stat in stats:
    print('Assigning %s:' % stat)
    print('Values left: %s' % str(values))
    val = int(input('Choose:'))
    assigned[stat] = val
    values.remove(val)

d = Dude(**assigned)
print(d)

对不起,Python 3,我相信你可以翻译(从你的问题中不带括号的印刷品判断 Py2.X)

【讨论】:

  • 其实我用的是 Python 3.7.4,但是我发现的教程最初是为旧版本设计的。谢谢!
【解决方案3】:

你可以做这样的事情,只要确保没有办法滥用它并改变不应该改变的东西的属性。这是一个例子:

class Test:
    def __init__(self):
        self.example = 'example'

t = Test()
t.example # 'example'
setattr(
    t, # your object (character)
    'example', # this means you're gonna change t.example
    'something else') # new value of t.example
t.example # 'something else'

【讨论】:

  • 我想我明白了。因此,使用我的示例,而不是将其附加到“有序值”,我将使用 `setattr(player, s, value)' 来获取我存储在 value 中的输入并将其分配给它当前迭代的任何统计信息?跨度>
猜你喜欢
  • 1970-01-01
  • 2012-11-09
  • 1970-01-01
  • 2022-07-06
  • 1970-01-01
  • 2010-11-15
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多