【问题标题】:In Python, what does dict.pop(a,b) mean?在 Python 中,dict.pop(a,b) 是什么意思?
【发布时间】:2010-12-31 17:44:58
【问题描述】:
class a(object):
    data={'a':'aaa','b':'bbb','c':'ccc'}
    def pop(self, key, *args):
            return self.data.pop(key, *args)#what is this mean.

b=a()
print b.pop('a',{'b':'bbb'})
print b.data

self.data.pop(key, *args)←------为什么还有第二个参数?

【问题讨论】:

  • 或者如果你真的很懒help(b.data.pop) REPL。

标签: python dictionary


【解决方案1】:

dicts 的pop 方法(如self.data,即{'a':'aaa','b':'bbb','c':'ccc'},此处)采用两个参数——参见the docs

第二个参数defaultpop 在第一个参数key 不存在时返回的值。 (如果您只使用一个参数 key 调用 pop,则如果该键不存在,则会引发异常。

在您的示例中,print b.pop('a',{'b':'bbb'}),这无关紧要,因为'a' b.data 中的一个键。但是如果你重复那行......:

b=a()
print b.pop('a',{'b':'bbb'})
print b.pop('a',{'b':'bbb'})
print b.data

您会看到它有所不同:第一个 pop 删除了 'a' 键,因此在第二个 pop 中实际上返回了 default 参数(因为 'a' 现在在 @987654339 中不存在@)。

【讨论】:

  • 只是一个小小的注释,我认为在某些情况下用户需要pop dict 的元素但保留弹出元素的值很重要。因此,dict.pop(key) 删除了 key 以及相关联的 value,但也返回了刚刚删除的 keyvalue。我发现它很有用...
  • @flamenco 这就是我对pop() 的期望——JavaScript、PHP、Java 等更多语言的常见行为,尽管并非所有语言都这样做——例如C++ .
【解决方案2】:
>>> def func(a, *args, **kwargs):
...   print 'a %s, args %s, kwargs %s' % (a, args, kwargs)
... 
>>> func('one', 'two', 'three', four='four', five='five')
a one, args ('two', 'three'), kwargs {'four': 'four', 'five': 'five'}

>>> def anotherfunct(beta, *args):
...   print 'beta %s, args %s' % (beta, args)
... 
>>> def func(a, *args, **kwargs):
...   anotherfunct(a, *args)
... 
>>> func('one', 'two', 'three', four='four', five='five')
beta one, args ('two', 'three')
>>> 

【讨论】:

  • 我阅读了几个问题,详见我的其他答案。我还阅读了 OPs 配置文件,并意识到我的其他答案是无用的。这个答案应该至少展示 *args 所做的部分工作,这就是我猜测的 OP 真正令人困惑的地方,尽管有这个主题。
  • @James,为额外的努力 +1。我对真正的问题得出了相同的结论。
【解决方案3】:

这里有很多问题。我看到至少两个,也许三个:

  • pop(a,b) 有什么作用?/为什么还有第二个参数?
  • *args 的用途是什么?

第一个问题在Python Standard Library 参考中得到了简单的回答:

pop(key[, 默认])

如果键在字典中,删除它并返回它的值,否则返回默认值。 如果没有给出默认值并且键不在字典中,则会引发 KeyError。


第二个问题在Python Language Reference:

如果存在“*标识符”形式, 它被初始化为一个接收元组 任何多余的位置参数, 默认为空元组。如果 形式“**标识符”存在,它是 初始化为新字典 接收任何多余的关键字 参数,默认为一个新的空 字典。

换句话说,pop 函数至少需要两个参数。前两个被分配名称selfkey;其余的被塞进一个名为args的元组中。

*args 在对self.data.pop 的调用中传递时,下一行发生的事情与此相反——元组*args 扩展为传递的位置参数。这在Python Language Reference中有解释:

如果语法 *expression 出现在 函数调用,表达式必须 评估为一个序列。元素来自 这个序列被当作它们 是额外的位置参数

简而言之,a.pop() 想要灵活并接受任意数量的位置参数,以便它可以将未知数量的位置参数传递给self.data.pop()

这为您提供了灵活性; data 现在恰好是 dict,所以 self.data.pop() 接受一个或两个参数;但是,如果您将data 更改为一个需要19 个参数来调用self.data.pop() 的类型,那么您根本不必更改a 类。不过,您仍然需要更改任何调用 a.pop() 的代码才能传递所需的 19 个参数。

【讨论】:

  • +1 表示努力。我担心 OP 的英语无法胜任阅读您的答案的任务。
  • 我是在阅读 OPs 简介之前写的。我现在已经阅读了上述个人资料并看到了其他几个 OP 问题。我刚刚做了另一次尝试,这次只使用代码:)
【解决方案4】:
def func(*args): 
    pass

当您以这种方式定义函数时,*args 将是传递给函数的参数数组。这允许您的函数在不提前知道要传递多少参数的情况下工作。

您也可以使用关键字参数来执行此操作,使用 **kwargs:

def func2(**kwargs): 
    pass

见:Arbitrary argument lists


在你的例子中,你定义了一个像字典一样的类。 dict.pop 方法定义为pop(key[, default])

您的方法没有使用default 参数。但是,通过使用*args 定义您的方法并将*args 传递给dict.pop(),您允许调用者使用default 参数。

换句话说,你应该能够使用你的类的pop 方法,比如dict.pop

my_a = a()
value1 = my_a.pop('key1')       # throw an exception if key1 isn't in the dict
value2 = my_a.pop('key2', None) # return None if key2 isn't in the dict

【讨论】:

    猜你喜欢
    • 2014-02-09
    • 2020-02-09
    • 2014-01-16
    • 1970-01-01
    • 2017-02-02
    • 2013-12-16
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    相关资源
    最近更新 更多