我正在尝试执行 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)
调用它,它将按预期工作,但是呃,如此丑陋且不直观...我显然在这里遗漏了一些东西。
任何提示表示赞赏,提前致谢。
I'm trying to do switch statement (with dictionary) and the answer needs to be a formatted string, so for example:
descriptions = {
'player_joined_clan': "%(player)s joined clan %(clan)s." % {"player": token1, "clan": token2},
#etc...
}
Now, this would work if those both tokens were always defined, which is not the case. Plus I believe it is formatting all the strings in the dictionary, which is not needed, it should only format the one that will be needed. So, I came up with this very unusual and partially dumb solution using lambda
descriptions = {
'player_joined_clan': lambda x: "%(player)s joined clan %(clan)s." % {"player": token1, "clan": token2},
}
Which I can then call with descriptions["player_joined_clan"](0)
, it will work as expected but ehh, so ugly and unintuitive... I'm clearly missing something here.
Any tips appreciated, thanks in advance.
发布评论
评论(3)
如果我理解正确,我会推荐 collections.defaultdict 。
这实际上并不是我所说的“switch”语句,但我认为最终结果接近您正在寻找的结果。
我可以用完整的代码、数据和应用程序来最好地解释。
显然,关键行是 defaultdict 行。
或者,如果您希望它比简单的带有一个字符串的 lambda 更具可定制性,您可以定义自己的 defaultdict 类,例如:
更改行以使用您的类而不是默认的类:
并且,瞧,输出:
请参阅文档对于 collections.defaultdict 了解更多示例。
编辑:
我忘记了这个 __missing__ 功能已添加到 python 2.5 中的标准 dict 类中。因此,更简单的方法甚至不涉及
collections.defaultdict
——只需子类dict
:If I'm understanding correctly, I'd recommend a collections.defaultdict.
This isn't really what I'd call a "switch" statement, but I think the end result is close to what you're looking for.
I can best explain with full code, data, and application.
Obviously, the key line is the defualtdict line.
Or, if you want it more customizable than simply a lambda with one string, you can define your own defaultdict class, such as:
change the line to use your class instead of the default one:
and, voila, the output:
See the documentation for collections.defaultdict for more examples.
Edit:
I forgot that this
__missing__
functionality was added to the standarddict
class in python 2.5. So an even simpler approach doesn't even involvecollections.defaultdict
-- just subclassdict
:我认为您希望描述字典仅包含格式字符串,例如:
然后您将有一个接收描述键和特定于事件的数据的字典的函数,该函数将生成格式化的消息,例如
:事实上,我认为您编写示例的方式,
token1
等将在声明descriptions
时进行评估——当我假设您想要的是使消息在不同时间针对这些变量的不同值进行格式化。I would think that you want the descriptions dictionary to contain only the format strings, e.g.:
Then you'd have a function that received a description key and a dictionary of event-specific data, that would produce the formatted message, something like:
In fact, I think that the way you have written your example,
token1
etc. would be evaluated at the time of the declaration ofdescriptions
-- when I presume what you want is for the message to be formatted for different values of these variables at different times.我认为您想要做的是添加另一个层,该层根据各种字典键的存在或不存在来选择格式化程序。
因此,您可以使用类似的方法
来确定将使用哪种格式字符串。请注意,我使用的是与
新样式格式字符串 >str.format
而不是旧式的。推荐使用它们而不是旧的template % data
模板。然后要获得格式化函数,您可以执行
然后调用
这比 case 语句要差,因为没有
default
case;如果您需要,可以将descriptions
的访问包装在try
...except KeyError
构造中,可能全部都在名为 <的函数中代码>格式描述。您可能希望子类化dict
并使其成为该类的方法,具体取决于代码的结构。I think what you want to do is add another layer that selects a formatter based on the presence or absence of the various dictionary keys.
So you could use something like
to establish which format string will be used. Note that I'm using the new-style format strings that work with
str.format
rather than the old-style ones. They're recommended over the oldertemplate % data
ones.And then to get a formatting function you can do
and then call
This is inferior to a case statement in that there's no
default
case; if you need that you could wrap the access ofdescriptions
in atry
...except KeyError
construct, probably all within a function called e.g.format_description
. You might want to subclassdict
and make this a method of that class, depending on how your code is structured.