如何将参数类型从str更改为命令命令

2024-10-04 11:25:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创造一个命令命令,该命令接受一个参数以使用消耗品(这是一个文本库)

import cmd
class Adventure(cmd.Cmd):
    prompt = ">"

# Other commands cut out because they are not part of the problem   

    def do_use(self, arg):
        arg.use(pc)

其中arg将是消耗品类的对象,具有自用(target)函数之前已经在代码中定义过(在本例中,是药剂对象)

class Consumable:
    def __init__(self, hpgain):
        self.hpgain = hpgain

    def use(self, target):
        inventory.remove(self)
        target.addhp(self.hpgain)

potion = Consumable(5)
inventory = []
inventory.append(potion)

pc玩家类的对象,其具有self.addhp文件(amount)函数已在代码中定义

class Player:
    def __init__(self, hp):
        self.hp = hp
        self.maxhp = hp

    def addhp(self, amount):
        self.hp += amount
        if self.hp > self.maxhp:
            self.hp = self.maxhp

pc = Player(20)

两者都药剂使用(pc)pc.addhp公司(amount)函数在标准Python shell中工作

当我尝试在自定义shell中使用药剂对象类型使用药剂时,出现以下错误:

Traceback (most recent call last):
  File "C:\Users\[Redacted]\Desktop\adventure.py", line 225, in <module>
    Adventure().cmdloop()
  File "C:\Python37\lib\cmd.py", line 138, in cmdloop
    stop = self.onecmd(line)
  File "C:\Python37\lib\cmd.py", line 217, in onecmd
    return func(arg)
  File "C:\Users\[Redacted]\Desktop\adventure.py", line 199, in do_use
    arg.use(pc)
AttributeError: 'str' object has no attribute 'use'

因此,它将函数的参数视为字符串而不是对象。我该怎么改变呢?你知道吗


Tags: 对象函数selfcmdusedeflinearg
2条回答

Cmd模块将每个参数解析为一个命令行参数,在本例中它是一个字符串。在Python中,有几种方法可以按名称查找当前加载到内存中的objectsglobals就是其中之一。如果您试图定位的对象恰好在另一个模块中声明,即(x=5),那么我们可以使用getattr(module_name, var_name)!你知道吗

class Adventure(cmd.Cmd):
    prompt = ">"

# Other commands cut out because they are not part of the problem   

    def do_use(self, arg):
        globals()[arg].use(pc) #if potion is declared in the current module
        #getattr(module_where_it_is_declared, arg).use(pc) #if potion is declared in another module

让我知道这是否有效!你知道吗

我将创建一个Inventory类,如下所示:

from cmd import Cmd
from collections import Counter


class Inventory(Counter):
    """
    We can extend the Inventory class later. For now it will work as a Counter
    so that we can keep track of the number of each item it has
    """


class Player:
    def __init__(self, hp):
        self.hp = hp
        self.maxhp = hp
        self.inventory = Inventory()

    def has(self, item_name):
        # Check that there is a positive amount of that item
        return item_name in self.inventory and self.inventory[item_name] > 0

    def use(self, item_name, item):
        # We are passing both the item_name and the item as we want to use it
        # We could also use the item itself as the key for the Inventory instead
        # of the item name, so that we do not need both (method has would also
        # need an update in that case)

        # Check if it is consumable to reduce the amount by one
        if isinstance(item, Consumable):
            self.inventory[item_name] -= 1

        # Use the item passing the player as it will have to access its addhp method
        item.use(self)

    def addhp(self, amount):
        self.hp += amount
        if self.hp > self.maxhp:
            self.hp = self.maxhp


class Consumable:  # You should probably add a base class Item later
    def use(self, player):
        pass  # This will be overwritten by other classes


class Potion(Consumable):
    """
    The Potion class allows to define different sizes of pots that will heal
    the player the specified amount.
    """
    def __init__(self, hp):
        """Define the amount of hp that a potion heals."""
        self.hp = hp

    def use(self, player):
        """Heal the player by the specified amount."""
        player.addhp(self.hp)


class Adventure(Cmd):
    prompt = ">"

    # This is just a map of item names to their current objects
    items = {
        "small potion": Potion(2),
        "potion": Potion(5),
        "big potion": Potion(10),
    }

    def __init__(self, *args, **kwargs):
        # Call parent class constructor IMPORTANT!
        super().__init__(*args, **kwargs)
        # Now we handle our own instance variables
        self.player = Player(20)

    def do_use(self, item_name):
        # Check before using
        if self.player.has(item_name):
            self.player.use(item_name, self.items[item_name])

do_use方法不是线程安全的,因此如果您在任意点添加不同的线程,请记住您应该在某个地方添加并使用锁。你知道吗

相关问题 更多 >