为什么python dict.update()不返回对象?

2024-10-06 17:34:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我想做的是:

award_dict = {
    "url" : "http://facebook.com",
    "imageurl" : "http://farm4.static.flickr.com/3431/3939267074_feb9eb19b1_o.png",
    "count" : 1,
}

def award(name, count, points, desc_string, my_size, parent) :
    if my_size > count :
        a = {
            "name" : name,
            "description" : desc_string % count,
            "points" : points,
            "parent_award" : parent,
        }
        a.update(award_dict)
        return self.add_award(a, siteAlias, alias).award

但如果在功能上觉得很麻烦,我宁愿这样做:

        return self.add_award({
            "name" : name,
            "description" : desc_string % count,
            "points" : points,
            "parent_award" : parent,
        }.update(award_dict), siteAlias, alias).award

为什么update不返回对象以便可以链接?

JQuery这样做是为了链接。为什么python不能接受它?


Tags: namecomhttpsizestringreturnmycount
3条回答
>>> dict_merge = lambda a,b: a.update(b) or a
>>> dict_merge({'a':1, 'b':3},{'c':5})
{'a': 1, 'c': 5, 'b': 3}

注意,除了返回合并的dict之外,它还修改了第一个参数。所以dict_merge(a,b)将修改a

或者,当然,你也可以直接做:

>>> (lambda a,b: a.update(b) or a)({'a':1, 'b':3},{'c':5})
{'a': 1, 'c': 5, 'b': 3}

按照惯例,Python的API区分了过程和函数。函数根据其参数(包括任何目标对象)计算新值;过程修改对象,不返回任何内容(即不返回任何内容)。所以过程有副作用,函数没有。update是一个过程,因此它不返回值。

这样做的动机是,否则,你可能会得到不良的副作用。考虑

bar = foo.reverse()

如果reverse(将列表反转到位)也会返回列表,用户可能会认为reverse返回了一个新的列表,该列表被分配给bar,并且永远不会注意到foo也被修改了。通过使reverse return None,他们立即意识到bar不是反转的结果,并且会更接近于reverse的效果。

Python主要实现了command-query separation:mutators返回None(带有实用主义诱导的异常,如pop;-),因此它们不可能与访问器混淆(同样,赋值不是表达式,语句-表达式分离在那里,等等)。

这并不意味着在你真正想要的时候没有很多方法可以把事情合并起来,例如,dict(a, **award_dict)使一个新的dict非常像你看起来希望返回的dict.update——所以如果你真的觉得它很重要,为什么不使用它呢?

编辑:顺便说一句,在您的特定情况下,不需要创建a一路上,或者:

dict(name=name, description=desc % count, points=points, parent_award=parent,
     **award_dict)

创建一个dict,其语义与您的a.update(award_dict)完全相同(包括在发生冲突的情况下,award_dict中的条目重写您显式给出的那些条目;要获得其他语义,即要使显式条目“赢得”此类冲突,请将award_dict作为唯一的位置参数传递,关键字之前一个,失去了**形式的dict(award_dict, name=name等)。

相关问题 更多 >