我正在使用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)
谢谢!
答案 0 :(得分:13)
我认为你可能对类和实例如何工作有一个轻微误导的概念。如果你想一想人,可能会更有意义。
假设我们想要在类层次结构中对人进行建模。现在,一个人必须有一个名字,如果你让他们说话,他们会说出他们的名字:
class Person(object):
def __init__(self, name):
self.name = name
def speak(self):
print "Hi! My name is {self.name}.".format(self=self)
然后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
。然后,您可以拥有这些实例(在我的口袋里,在商店里,无论哪里)。如果你想使用药水,你可以使用特定的,即该类的一个实例。
答案 1 :(得分:2)
你在那里使用的代码使用了非常令人困惑的命名约定,我认为这会引起你的困惑--- 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