从类中为类创建动态变量

时间:2014-01-14 01:45:39

标签: python class variables python-2.7 dynamic-data

对于上下文,我正在使用RPG中的库存系统,我正在用python代码进行原型设计。

我不明白的是如何为项目的每个实例创建单独的变量而不手动声明它们。举个简短​​的例子:

class Player(object):
    def __init__(self):
        self.Items = {}

class Item(object):
    def __init__(self):
        self.Equipped = 0

class Leather_Pants(Item):
    def __init__(self):
        #What do i place here?
    def Pick_Up(self, owner):
        owner.Items[self.???] = self #What do i then put at "???"
    def Equip(self):
        self.Equipped = 1
PC = Player()
#Below this line is what i want to be able to do
Leather_Pants(NPC) #<-Create a unique instance in an NPC's inventory
Leather_Pants(Treasure_Chest5) #Spawn a unique instance of pants in a treasure chest
Leather_Pants1.Pick_Up(PC) #Place a specific instance of pants into player's inventory
PC.Items[Leather_Pants1].Equip() #Make the PC equip his new leather pants.

如果我在上面的代码中做了些蠢事,请指出。

如果代码不清楚,我想要做的是我希望能够在我生成它们的同时动态创建所有项目的变量,因此没有两个项目将共享相同的变量名称我的标识符。

我不介意我是否必须使用其他类或函数,如“Create_Item(Leather_Pants(),Treasure_Chest3)”

最好的方法是什么,或者如果你认为我做错了,哪种方式会更正确?

2 个答案:

答案 0 :(得分:5)

作为一般规则,you don't want to create dynamic variables,您想要keep data out of your variable names

不是试图创建名为pants0pants1等的变量,为什么不创建所有皮裤的单一列表呢?然后你只需pants[0]pants[1]等等。你的代码的其他任何部分都不得知道裤子的存储方式。所以你所有的问题都消失了。

同时,您可能不希望创建Leather_Pants来自动将自己添加到全局环境中。只需正常分配即可。

所以:

pants = []
pants.append(Leather_Pants(NPC))
pants.append(Leather_Pants(chests[5]))
pants[1].pickup(PC)

裤子不必知道他们是#1。每当你对它们调用一个方法时,它们就会得到一个self参数。并且玩家的物品不需要为每个物品映射一些任意名称;只需将项目直接存储在列表或集合中。像这样:

class Player(object):
    def __init__(self):
        self.Items = set()

class Item(object):
    def __init__(self):
        self.Equipped = 0

class Leather_Pants(Item):
    def __init__(self):
        pass # there is nothing to do here
    def Pick_Up(self, owner):
        self.owner.Items.add(self)
    def Equip(self):
        self.Equipped = 1

答案 1 :(得分:1)

Abernat已经解决了一些问题,但我认为我还有一些问题。

您似乎正在使用OOP,但是在对象中混合了一些问题。例如,我的裤子不管他们是否穿着,我关心的原因很多。在python术语中,Pants类不应该跟踪它是否具有装备(只有它是可装备的),Player类应该:

class CarryableItem:
   isEquipable = False
class Pants(CarryableItem):
   isEquipable = True      

class Player:
  def __init__(self):
    self.pants = None   # Its chilly in here
    self.shirt = None   # Better take a jumper
    self.inventory = [] # Find some loot
  def equip(self,item):
    if is.isEquipable:
      pass # Find the right slot and equip it,
           # put the previously equipped item in inventory, etc...

此外,很少有一件物品需要知道它的拥有者是谁,或者它被抓住了,所以这样的动词应该再次进入玩家:

class Player:
  maxCarry = 10
  def take(Item):
    if len(inventory) < maxCarry:
       inventory.append(item)

最后,虽然我们已经尝试将大多数动词移到实际做事的演员身上,但有时情况并非如此。例如,在实例化胸部时:

import random
class StorageItem:
  pass
class Chest(StorageItem):
  __init__(self):
    self.storage = random.randint(5)
    self.loot = self.spawnLoot()
  def spawnLoot(self):
    for i in range(self.storge):
      # Lets make some loot
      item = MakeAnItem # Scaled according to type level of dungeon, etc.
      loot.append(item)
  def remove(item):
    self.loot[self.loot.index(item)]=None

现在关于玩家想要掠夺胸部时该怎么做的问题?

class Player:
  def plunder(storage):
    for item in storage.loot:
      # do some Ui to ask if player wants it.
      if item is not None and self.wantsItem(item) or \
          (self.name="Jane" and self.wantsItem(item) and self.doesntWantToPay):
        self.take(item)
        storage.remove(item)

编辑:回答评论:

如果您对计算护甲等感到好奇,那么这又是用户的一个因素,而不是项目。例如:

class Player:
  @property
  def clothing(self):
    return [self.pants,self.top]
  @property
  def armorClass(self):
    ac = self.defence
    for item in self.clothing:
      def = item.armorClass
        if self.race="orc":
          if item.material in ["leather","dragonhide"]:
            def *= 1.5 # Orcs get a bonus for wearing gruesome dead things 
        elif item.material in ["wool","silk"]:
          def *= 0.5 # Orcs hate the fineries of humans
      ac += def
    return ac
pants = Pants(material="leather")
grum = Player(race="orc")
grum.equip(pants)

print grum.armorClass
>>> 17 # For example?