简体   繁体   English

PYTHON 使用来自用户输入的名称调用 class object

[英]PYTHON Call an class object with a name that is from user-input

Basically, The user creates a creature by giving it a name, this name is then fed into the creation of the creature, where it is then given stats (This all works fine, even when making several creatures).基本上,用户通过给它一个名字来创建一个生物,然后这个名字被输入到这个生物的创建中,然后它被赋予了统计数据(这一切都很好,即使在制作几个生物时也是如此)。 However, I want to give the option to the user to check the stats of the creature they created through the 'check_stats()' function, they do this by inputting the slot number of the creature in their line-up, the code then finds the name of the creature through this, and calls the check_stat function using it.但是,我想为用户提供选项来检查他们通过'check_stats()' function 创建的生物的统计信息,他们通过在他们的阵容中输入生物的插槽号来做到这一点,然后代码找到通过此生物的名称,并使用它调用 check_stat function。 However this does not work as I receive the error:但是,这不起作用,因为我收到错误:

AttributeError: 'str' object has no attribute 'check_stats'

If i create the creature manually in the code, like I write:如果我在代码中手动创建生物,就像我写的那样:

Bill = Pet('Bill')

It works perfectly and i can call the stats whenever.它运行良好,我可以随时调用统计信息。 Its just when the user creates the class instance, it does not work.就在用户创建 class 实例时,它不起作用。

This is my code (That is the problem):这是我的代码(这就是问题所在):

def create_creature():
    creature = Pet(name)
    creature.create_stats()
    print(" \n \n \n")

minions = {}
minion_value = {
    1: None,
    2: None,
    3: None,
    4: None,
    5: None,
    6: None
}

minion_slot = 0
for value in range(2):
    name = input("Create a pet!\n> ")
    minions[name] = create_creature()
    minion_slot += 1
    minion_value.update({minion_slot : name})


print("Your line-up")
for creature_ in minion_value:
    print("{}: {}".format(creature_, minion_value[creature_]))

check_creature = int(input("Which pet would you like to check? (number)\n> "))
for creature_ in minion_value:
    if check_creature == creature_:
                (minion_value[check_creature]).check_stats()

This is what the output of this code looks like:这是此代码的 output 的样子:

Create a pet!
> Bob
---Bob---
3 years old 
5% healthy
66% happy
65% crazy
48% smarts
 
 
 

Create a pet!
> Bill
---Bill---
9 years old 
100% healthy
35% happy
93% crazy
13% smarts
 
 
 

Your line-up
1: Bob
2: Bill
3: None
4: None
5: None
6: None
Which pet would you like to check? (number)
> 1
Traceback (most recent call last):
  File "C:\Users\c10ld\Downloads\Test_class_animals.py", line 103, in <module>
    (minion_value[check_creature]).check_stats()
AttributeError: 'str' object has no attribute 'check_stats'

This is what it should look like:这应该是这样的:

Create a pet!
> Bob
---Bob---
3 years old 
5% healthy
66% happy
65% crazy
48% smarts
 
 
 

Create a pet!
> Bill
---Bill---
9 years old 
100% healthy
35% happy
93% crazy
13% smarts
 
 
 

Your line-up
1: Bob
2: Bill
3: None
4: None
5: None
6: None
Which pet would you like to check? (number)
> 1

Your Pet:
---Bob---
3 years old 
5% healthy
66% happy
65% crazy
48% smarts

Can anyone help me?谁能帮我? Thank you, (Sorry if this is too long. its my first post and i wanted to make sure there was little to no confusion.)谢谢,(对不起,如果这太长了。这是我的第一篇文章,我想确保几乎没有混淆。)

EDIT: Here is the rest of the code, including the Pet class:编辑:这是代码的 rest,包括宠物 class:

import random



class Animal(object):
    def __init__(self, age, health, happiness):
        self.age = 0
        self.health = 0
        self.happiness = 0
        
        
    def get_age(self):
        self.age = random.randint(8, 100)
 
    def get_health(self):
        self.health = random.randint(1, 100)
        print(f"{self.health}% healthy")
     
    def get_happiness(self):
        self.happiness = random.randint(1, 100)
        print(f"{self.happiness}% happy")
        
    def age_up(self):
        self.age += 1
        print(f"{int(round(self.age, 0))} years old")
        
        if self.age < 17:    
                self.age_up()
            
        elif self.age >= 17:
                print("died of age.")



class Pet(Animal):
    def __init__(self, name):
        self.name = name
        self.craziness = 0
        self.intelligence = 0
    
    
    def pet_age(self):
       self.get_age()
       self.age = self.age / 7
       print(f"{int(round(self.age, 0))} years old ")
       
         
    def get_craziness(self):
        self.craziness = random.randint(1,100)
        print(f"{self.craziness}% crazy")
        
    def get_intelligence(self):
        self.intelligence = random.randint(1, 100)
        print(f"{self.intelligence}% smarts")
        
    def create_stats(self):
         print(f"---{self.name}---")
         self.pet_age()
         self.get_health()
         self.get_happiness()
         self.get_craziness()
         self.get_intelligence()
         
    def check_stats(self):
         print(f"---{self.name}---")
         print(f"{int(round(self.age, 0))} years old")
         print(f"{self.health}% healthy")
         print(f"{self.happiness}% happy")
         print(f"{self.craziness}% crazy")
         print(f"{self.intelligence}% smarts")

I created an 'Animal' class as i was planning on creating more sub-classes, such as workers and warriors!我创建了一个“动物”class,因为我正计划创建更多的子类,例如工人和战士!

You need to pass the variable as an argument:您需要将变量作为参数传递:

Random example (you should be able to apply the same logic to your code):随机示例(您应该能够将相同的逻辑应用于您的代码):

class Person(object):
    def __init__(self, name):
        self.name = name

my_name = input("What is your name? ")
p = Person(my_name)
print(p.name)

Output: Output:

What is your name? 
Ryan
Ryan

It seems you are storing just the name of the creature in your minion_value dictionary.看来您只是将生物的名称存储在minion_value字典中。 This is why (minion_value[check_creature]) from这就是为什么(minion_value[check_creature])来自

check_creature = int(input("Which pet would you like to check? (number)\n> "))
for creature_ in minion_value:
    if check_creature == creature_:
                (minion_value[check_creature]).check_stats()

is returning a str which has no check_stats method defined from your custom Pet class.正在返回一个str ,它没有从您的自定义Pet class 定义的 check_stats 方法。

So, we can do this.所以,我们可以做到这一点。

for value in range(2):
    name = input("Create a pet!\n> ")
    minions[name] = create_creature(name)
    minion_value.append(minions[name])

and for the create_creature function,对于create_creature function,

def create_creature(name: str) -> Pet:
    creature = Pet(name)
    creature.create_stats()
    print(" \n \n \n")
    return creature

Thank you for providing further code.感谢您提供更多代码。 Let's see..让我们来看看..

class Pet(Animal):
    ...(after __init__)...
    def __str__(self):
        return self.name # it's that simple :)

I checked the documentation and __repr__ is for more technical representations whereas __str__ is for the end user, like the player.我检查了文档__repr__用于更多技术表示,而__str__用于最终用户,例如播放器。

We can also add getter and setter decorators to the code for more elegance.我们还可以在代码中添加 getter 和 setter 装饰器,以获得更优雅的效果。 I'll add that soon too!我也会尽快补充的!

To improve readability and reduce memory usage, we can also use a list instead a dictionary for the minion_value object.为了提高可读性并减少 memory 的使用,我们还可以为minion_value object 使用列表而不是字典。 Edit: Thank you for your reply.编辑:感谢您的回复。 I changed the for loop code above for reference.我更改了上面的 for 循环代码以供参考。

And as others have suggested, it is wise to constrain global variables and pass necessary arguments as a parameter to a function.正如其他人所建议的那样,明智的做法是约束全局变量并将必要的 arguments 作为参数传递给 function。 Edit: Great you stuck with it.编辑:太好了,你坚持下去了。 I'm glad it worked as you intended.我很高兴它按您的预期工作。

Thank you for your question, and your game looks really fun!谢谢你的提问,你的游戏看起来很有趣!

Edit: As we changed the minion_value to be an empty list minion_value = [] , we should change the line_up code as well.编辑:当我们将minion_value更改为空列表minion_value = []时,我们也应该更改line_up代码。 f-strings are a useful toolkit for formatting. f-strings是一个有用的格式化工具包。 see here看这里

print("Your line-up")
for i, creature_ in enumerate(minion_value):
    print(f"{i}: {creature_}")

or或者

print("Your line-up")
for i in range(1, 7):
    try:
        print(f"{i}: {minion_value[i]}")
    except IndexError:
        print(f"{i}: None")

There are many things wrong with the code here.这里的代码有很多问题。

Firstly, create_creature does not return anything, which in Python means return None , so I don't think you know what you meant to store in minions when you do minions[name] = create_creature() .首先, create_creature不返回任何内容,这在 Python 中表示返回None ,所以我认为您在执行 minions minions[name] = create_creature()时不知道您打算在 minions 中存储什么。

Then, create_creature also appears to be using a name variable, which is not assigned in it or given as argument, so where does the name come from?然后, create_creature似乎也使用了一个name变量,它没有在其中分配或作为参数给出,那么名称来自哪里?

Then, the minion_value is a dict with integer keys from 1 to 7, that looks like a list to me.然后, minion_value是一个字典,其中 integer 键从 1 到 7,在我看来就像一个列表。

Finally, you are storing name in minion_value which must be a str rather than a Pet, and so that is why you get the attribute error for missing .check_stats() , which is defined for Pet but not str .最后,您将name存储在minion_value中,它必须是 str 而不是 Pet,这就是为什么您会收到缺少.check_stats()的属性错误,该属性是为Pet而不是str定义的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM