Skip to main content
 首页 » 编程设计

python之唯一常量引用

2025年05月04日31yxwkf

让我们以下面的代码为例:

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} 

get_values 函数返回一个带有给定键的字典,如果参数是可迭代对象则返回 keys,如果参数是 None 则返回空字典,如果参数是常量 ALL 则返回整个字典。

当您想要返回一个名为“everything”的键时,就会出现这个问题。 Python 可能对 ALL 和参数使用相同的引用(因为它们都是相同的不可变),这将使 keys is ALL 表达式为 True。因此,该函数将返回整个字典,而不是预期的行为。

可以将 ALL 分配给专门为此目的定义的类的实例对象,或者使用 type 方法生成内联对象,这将使 ALL 成为唯一引用。不过,这两种解决方案似乎都有些矫枉过正。

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

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

请您参考如下方法:

不要使用可能(不费吹灰之力)成为有效 key 的值作为标记。

ALL = object() 

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

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 

在最后一种情况下,我们利用了 get_all_values 可以采用 any 可迭代的事实,并且 dict 上的迭代器迭代它的键。