独特的常量参考

plo*_*tch 1 python

我们以下面的代码为例:

ALL = "everything"

my_dict = {"random":"values"}

def get_values(keys):
    if keys is None:
        return {}
    if keys is ALL:
        return my_dict
    if not hasattr(keys, '__iter__')
        keys = [keys]
    return {key: my_dict[key] for key in keys}
Run Code Online (Sandbox Code Playgroud)

该函数get_values返回带有给定键的dict,如果参数是可迭代的则返回键,如果参数是None则返回空字典,如果参数是常量ALL则返回整个字典.

当你想要返回一个名为"everything"的键时,会发生这种问题.Python可能对ALL和参数​​使用相同的引用(因为它们都是相同的不可变的),这将构成keys is ALL表达式True.因此,该函数将返回整个dict,因此不会返回预期的行为.

可以分配ALL给专门为此目的定义的类的实例对象,或者使用该type方法生成内联对象,这将使ALL成为唯一引用.但这两种解决方案看起来都有些过分.

我也可以在函数声明中使用一个标志(即:)def get_values(keys, all=False),但是我总是可以从另一个中获取参数的值(if all is True,then keys is None,if keys is not None,then All is not False),所以它看起来过于冗长.

您对前面提到的技术有何看法,您是否看到了其他可能的解决方法?

che*_*ner 5

不要使用可能(没有极大努力)有效密钥作为哨兵的值.

ALL = object()
Run Code Online (Sandbox Code Playgroud)

但是,定义函数以获取(可能为空)键序列似乎要简单得多.

def get_values(keys=None):
    if keys is None:
        keys = []
    rv = {}
    for key in keys:
        # Keep in mind, this is a reference to
        # an object in my_dict, not a copy. Also,
        # you may want to handle keys not found in my_dict:
        # ignore them, or set rv[key] to None?
        rv[key] = my_dict[key]
    return rv

d1 = get_all_values()   # Empty dict
d2 = get_all_values([])  # Explicitly empty dict
d3 = get_all_values(["foo", "bar"])  # (Sub)set of values
d4 = get_all_values(my_dict) # A copy of my_dict
Run Code Online (Sandbox Code Playgroud)

在最后一种情况下,我们利用get_all_values可以采用任何可迭代的事实,并通过dict遍历其键的迭代器.