我正在尝试使用switch语句(使用字典),答案需要是格式化字符串,例如:
descriptions = {
'player_joined_clan': "%(player)s joined clan %(clan)s." % {"player": token1, "clan": token2},
#etc...
}
现在,如果始终定义这两个令牌,这将起作用,但实际情况并非如此。另外我相信它是格式化字典中的所有字符串,这是不需要的,它应该只格式化所需的字符串。所以,我想出了使用lambda
这个非常不寻常和部分愚蠢的解决方案descriptions = {
'player_joined_clan': lambda x: "%(player)s joined clan %(clan)s." % {"player": token1, "clan": token2},
}
然后我可以用descriptions["player_joined_clan"](0)
调用它,它会按预期工作但是呃,如此丑陋和不直观......我显然在这里遗漏了一些东西。
提前感谢任何提示。
答案 0 :(得分:3)
如果我理解正确,我建议collections.defaultdict。 这不是我所谓的“切换”声明,但我认为最终结果接近您所寻找的。 p>
我可以用完整的代码,数据和应用程序来解释。 显然,关键是defualtdict线。
>>> import collections
>>>
>>> descriptions = {
... 'player_joined_clan' : '%(player)s joined clan %(clan)s',
... 'player_left' : '%(player)s left',
... 'player_hit_player' : '%(player)s (of %(clan)s) hit %(player2)s (of %(clan2)s)',
... }
>>>
>>> data = [
... {'player': 'PlayerA'},
... {'player': 'PlayerB', 'clan' : 'ClanB'},
... {'clan' : 'ClanC'},
... {'clan' : 'ClanDA', 'player2': 'PlayerDB'},
... ]
>>>
>>> for item in data:
... print item
... item = collections.defaultdict(lambda : '"<unknown>"', **item)
... for key in descriptions:
... print ' %s: %s' % (key, descriptions[key] % item)
... print
...
{'player': 'PlayerA'}
player_joined_clan: PlayerA joined clan "<unknown>"
player_left: PlayerA left
player_hit_player: PlayerA (of "<unknown>") hit "<unknown>" (of "<unknown>")
{'clan': 'ClanB', 'player': 'PlayerB'}
player_joined_clan: PlayerB joined clan ClanB
player_left: PlayerB left
player_hit_player: PlayerB (of ClanB) hit "<unknown>" (of "<unknown>")
{'clan': 'ClanC'}
player_joined_clan: "<unknown>" joined clan ClanC
player_left: "<unknown>" left
player_hit_player: "<unknown>" (of ClanC) hit "<unknown>" (of "<unknown>")
{'clan': 'ClanDA', 'player2': 'PlayerDB'}
player_joined_clan: "<unknown>" joined clan ClanDA
player_left: "<unknown>" left
player_hit_player: "<unknown>" (of ClanDA) hit PlayerDB (of "<unknown>")
或者,如果您希望它比仅包含一个字符串的lambda更具可定制性,您可以定义自己的defaultdict类,例如:
class my_defaultdict(collections.defaultdict):
def __missing__(self, key):
return '<unknown %s>' % key
更改该行以使用您的类而不是默认类:
#item = collections.defaultdict(lambda : '"<unknown>"', **item)
item = my_defaultdict(**item)
,瞧,输出:
{'player': 'PlayerA'}
player_joined_clan: PlayerA joined clan <unknown clan>
player_left: PlayerA left
player_hit_player: PlayerA (of <unknown clan>) hit <unknown player2> (of <unknown clan2>)
{'clan': 'ClanB', 'player': 'PlayerB'}
player_joined_clan: PlayerB joined clan ClanB
player_left: PlayerB left
player_hit_player: PlayerB (of ClanB) hit <unknown player2> (of <unknown clan2>)
{'clan': 'ClanC'}
player_joined_clan: <unknown player> joined clan ClanC
player_left: <unknown player> left
player_hit_player: <unknown player> (of ClanC) hit <unknown player2> (of <unknown clan2>)
{'clan': 'ClanDA', 'player2': 'PlayerDB'}
player_joined_clan: <unknown player> joined clan ClanDA
player_left: <unknown player> left
player_hit_player: <unknown player> (of ClanDA) hit PlayerDB (of <unknown clan2>)
有关更多示例,请参阅collections.defaultdict的文档。
修改强>
我忘了这个__missing__
功能被添加到python 2.5中的标准dict
类中。因此,更简单的方法甚至不涉及collections.defaultdict
- 只是子类dict
:
class my_defaultdict(dict):
def __missing__(self, key):
return '<unknown %s>' % key
答案 1 :(得分:1)
我认为您希望描述字典仅包含格式字符串,例如:
descriptions = {
'player_joined_clan': "%(player)s joined clan %(clan)s.",
#etc...
}
然后你有一个函数接收一个描述键和一个特定于事件的数据字典,它会产生格式化的消息,如:
def getMessage( key, eventDataDict ):
return descriptions[key] % eventDataDict
事实上,我认为您编写示例的方式token1
等将在descriptions
声明时进行评估 - 当我假设您想要的是在不同时间为这些变量的不同值格式化的消息。
答案 2 :(得分:1)
我认为你要做的是添加另一个层,根据各种字典键的存在与否来选择格式化程序。
所以你可以使用像
这样的东西formatters = {
set('player', 'team'): "{player} joined {team}".format,
set('player'): "Hello {player}.".format,
set('team'): "{team} FTW!".format,
set(): "Something happened.".format}
确定将使用哪个格式字符串。请注意,我使用的是与str.format
配合使用的new-style format strings,而不是旧式的template % data
。他们被推荐使用较旧的fmt = descriptions[set(eventDataDict.keys())]
个。
然后获得格式化功能
formatted_greeting = fmt(eventDataDict)
然后致电
default
这不如案例陈述,因为没有descriptions
个案;如果您需要,可以在try
... except KeyError
构造中包含format_description
的访问权限,可能所有内容都在例如dict
。您可能希望子类化{{1}}并将其作为该类的方法,具体取决于代码的结构。