Если я правильно понимаю, я бы порекомендовал collection.defaultdict .На самом деле это не то, что я бы назвал выражением «switch», но я думаю, что конечный результат близок к тому, что вы ищете.
Я могу лучше всего объяснить с полным кодом, данными и приложением,Очевидно, что ключевой строкой является строка 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>")
Или, если вы хотите, чтобы она была более настраиваемой, чем просто лямбда с одной строкой, вы можете определить свой собственный класс 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>)
См. Документацию по collection.defaultdict для дополнительных примеров.
Редактировать:
Я забыл, что эта функциональность __missing__
была добавлена к стандартному классу dict
в Python 2.5.Таким образом, даже более простой подход даже не включает collections.defaultdict
- просто подкласс dict
:
class my_defaultdict(dict):
def __missing__(self, key):
return '<unknown %s>' % key