繁体   English   中英

Python为单个对象/类创建多个实例

[英]Python creating multiple instances for a single object/class

我正在使用Python。 我已经阅读了一些有关此内容的内容,似乎无法将其包裹住。 我想做的是创建一个名为Potions的类,其中包含各种药水对象。 现在有一个药水,一个简单的HealthPotion。 我希望药水可以堆叠在库存和商店库存中。 因此,我需要一个库存的药水量实例以及每个携带药水的商店库存的实例。 药水的数量是动态的,用于药水的购买/出售和抢劫。 如果有人可以提供基本的解释或示例,那将很好。

这是我所拥有的片段:

class Potion(Item):
    def __init__(self, name, desc, val, amt, type, effect, bound):
        Item.__init__(self, name, desc, val, amt, type, effect, bound)

        self.name = name
        self.desc = desc
        self.val = val
        self.amt = amt
        self.type = 0 #Restorative
        self.effect = effect

   def use(self, you):
    #Use health potion
        you.hp_current += self.effect
        you.displayStats()

#Format: Name, Description, Value, Amount, Type, Effect, Bound
HealthPotion = Potion('Health Potion', 'Restores 10 hit points when consumed', 10, 0, 
0, 10, 0)

理想情况下,默认数量应设置为0,这样我就可以宣布某家商店的库存量为多少。 库存和商店库存被设置为一个数组,在该数组中添加和删除项目。 我想我对这如何工作缺乏逻辑,我只是​​在举例说明金额上遇到了麻烦。

编辑:这是我拥有的一种购买方法的一部分,以查看不使用实例就会发生什么。 这很丑陋,我发现you.inventory.y.amt无法正常工作。 y是从“商店”中显示的项目列表中选择的项目。

            x = selection - 1 #Item menu starts at 1. But arrays start at 0. So it takes user input and subtracts 1 to match the array.
            y = self.stock[x]

            if y.val <= you.coin:
                if y.amt == 0:
                    you.inventory.append(y)
                    you.inventory.y.amt += 1
                else:
                    you.inventory.y.amt += 1;

                you.coin -= y.val
                self.funds += y.val

                if self.stock.y.amt > 1:
                    self.stock.y.amt -= 1
                else:
                    self.stock.y.amt -= 1
                    self.stock.pop(x)

我看过这样的例子:

class foo: 
a = 1 
i = foo() 
foo.a => 1 
i.a => 1 
i.a = "inst" 
foo.a => 1
i.a => "inst"

我想知道是否我不只是创建第二个HealthPotion对象,但这听起来不对。 这个例子使我另想。 也许我只是不了解实例化。

“这将创建Employee类的第一个对象”

emp1 = Employee("Zara", 2000)

“这将创建Employee类的第二个对象”

emp2 = Employee("Manni", 5000)

谢谢!

我认为您可能对类和实例的工作原理有些误解。 如果您改为考虑别人,这可能会更有意义。

假设我们要在类层次结构中对人建模。 现在,一个人必须有一个名字,如果您要求他们说,他们会说出他们的名字:

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

    def speak(self):
        print "Hi! My name is {self.name}.".format(self=self)

那么Person一个实例就是一个person! 例如:

>>> basil = Person("Basil")
>>> polly = Person("Polly")
>>> 
>>> basil.speak()
Hi! My name is Basil.
>>> polly.speak()
Hi! My name is Polly.
>>> basil == polly
False

因此,实例不是一种人,它实际上只是一个人。

我听不到你问的,你不能有一个实例本身就是类的类吗? 是的,当然可以! 它称为元类,在某些情况下是非常强大的工具。 但是,这些不是。


现在,如果您看一下自己的情况,您看到了区别吗? HealthPotion不是一种特殊的药水(比如说,这是我的口袋里药水),它是一种药水。 我们通过类继承来表达这种关系:定义一个新类HealthPotion ,该类继承自Potion 然后,您可以拥有这些实例(在我的口袋里,在商店中的任何地方)。 如果要使用一种药水,则可以使用一种特定的药水,即该类的一个实例。

您那里的代码使用了非常令人困惑的命名约定,我认为这使您感到困惑-HealthPotion不是一个类,而是一个实例,但是CamelCase名称表明它是python中的一个类。

要使用您的药水类来使用多种健康药水,只需

health_potion_1 = Potion("Health Potion", ...)
health_potion_2 = Potion("Health Potion", ...)
foobar_potion_1 = Potion("Foobar Potion", ...)
#...

尽管这是非常糟糕的样式,但您可能想要的是拥有一种方法来轻松创建具有相似特性的,具有不同效果的药水和相似的药水

为此,您应该

class HealthPotion(Potion):
    def __init__(self, name="Health Potion", effect=10):
        super(HealthPotion, self).__init__(name, "Restores %d points of health" % (effect, ), effect, 0, 0)
    def use(self, you):
        you.hp_current+=self.effect

如果要在一个清单中包含多个项目,则最简单的方法是简单地为清单创建一个清单(或集合或某个集合),并在清单中包含多个实例,例如

inventory = [HealthPotion(), HealthPotion()]

如果您想进行堆叠,我仍然认为这是库存的功能,而不是物品的功能(除了item.stackable成员之外),因此我将拥有一个Inventory类来处理对象的集合,例如人员的内容,胸部或商店。 一个简单的实现就是包装

inventory = [(HealthPotion(), 2)]

其中任何相同的项目都表示为一对项目和金额

另外,如果您有stacks_with方法,则很容易将前者转换为后者:

def stack_size(item, inv):
    "The number of items that will stack with item in inv"
    return len([i for i in inv if item.stacks_with(i)])

def stacked_inventory(inv):
    # if there is no stackable pair in the first i items
    # (i.e. the stack size for that item is 0 in inv[0:i]),
    # then the 'i'th item is a new stack,
    # with stack_size(inv[i], inv) items in it
    stacks = [ (inv[i], stack_size(inv[i]))
                  for i in range(0,len(inv)) 
                  if not stack_size(inv[i], inv[0:i])]
    return stacks

暂无
暂无

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

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