【发布时间】:2013-10-22 15:42:01
【问题描述】:
我昨天刚开始构建一个基于文本的游戏,作为学习 Python 的练习(我使用的是 3.3)。我说的是“基于文本的游戏”,但我的意思更多的是 MUD,而不是选择你自己的冒险。无论如何,当我昨天弄清楚如何使用super() 处理继承和多重继承时,我真的很兴奋,但是我发现参数传递确实使代码变得混乱,并且需要处理大量松散的小变量。此外,创建保存文件似乎是一场噩梦。
所以,我想,“如果某些类层次结构只接受一个参数,一个字典,然后将字典传回怎么办?”举个例子,这里有两个类精简为它们的 init 方法:
class Actor:
def __init__(self, in_dict,**kwds):
super().__init__(**kwds)
self._everything = in_dict
self._name = in_dict["name"]
self._size = in_dict["size"]
self._location = in_dict["location"]
self._triggers = in_dict["triggers"]
self._effects = in_dict["effects"]
self._goals = in_dict["goals"]
self._action_list = in_dict["action list"]
self._last_action = ''
self._current_action = '' # both ._last_action and ._current_action get updated by .update_action()
class Item(Actor):
def __init__(self,in_dict,**kwds)
super().__init__(in_dict,**kwds)
self._can_contain = in_dict("can contain") #boolean entry
self._inventory = in_dict("can contain") #either a list or dict entry
class Player(Actor):
def __init__(self, in_dict,**kwds):
super().__init__(in_dict,**kwds)
self._inventory = in_dict["inventory"] #entry should be a Container object
self._stats = in_dict["stats"]
将被传递的示例字典:
playerdict = {'name' : '', 'size' : '0', 'location' : '', 'triggers' : None, 'effects' : None, 'goals' : None, 'action list' = None, 'inventory' : Container(), 'stats' : None,}
(一旦字典通过,None 将被 {} 替换。)
因此,in_dict 被传递给前一个类,而不是 **kwds 的巨大负载。 我喜欢这个,因为:
- 它使我的代码更整洁、更易于管理。
- 只要字典至少有一些被调用键的条目,它就不会破坏代码。此外,给定的参数是否从未被使用也没关系。
- 文件 IO 似乎变得容易多了(存储为 dicts 的玩家数据字典、存储为 dicts 的项目数据字典等)
我明白了**kwds 的意思(编辑:显然我没有),并且在传递更少的参数时似乎并不麻烦。这只是似乎是一种在创建每个实例时处理大量属性需求的舒适方式。
也就是说,我仍然是一个主要的 python 菜鸟。所以,我的问题是这样的:是否有一个潜在的原因为什么通过 super() 将相同的 dict 反复传递给基类会比仅仅用讨厌的(又大又杂乱的)**kwds 传递更糟糕的主意?(例如,我这个级别的人可能不知道的口译员问题。)
编辑:
以前,创建一个新的 Player 可能看起来像这样,为每个属性传递一个参数。
bob = Player('bob', Location = 'here', ... etc.)
需要的参数数量激增,我只包括了真正需要存在的属性,以免中断来自 Engine 对象的方法调用。
这是迄今为止我从答案和 cmets 中得到的印象:
发送同一个字典并没有什么“错误”,只要没有机会修改它的内容(Kirk Strauser)并且字典总是有它应该有的东西(goncalopp)。真正的答案是问题错了,使用in_dict 而不是**kwds 是多余的。
这是正确的吗? (另外,感谢您提供的丰富多样的反馈!)
【问题讨论】:
-
也许我错过了问题的重点,但
kwds是一个字典,可以像一个一样使用。使用**只是提供了另一种调用方式。你可以打电话给Player(**playerdict),怎么这么乱? -
请记住,
**kwds是函数接受字典作为参数的一种方式。只是(a)调用它的语法与接受单个参数的函数不同,该参数应该是字典; (2) 如果每个函数依次采用**kwds并用__init__(**kwds)调用,则与如果采用kwds并用kwds调用相比,则有一个额外的副本。 -
@cmd 原始模型涉及传递大量单独的参数(其中许多是现在正在相关字典中传递的字典),这些参数会很混乱。基本上,卡尔所描述的。
标签: python python-3.x dictionary super