在列表上调用方法时语法不同的区别

时间:2018-07-07 20:55:35

标签: python

如果我有

things = ["Dog", "Zebra", "Cow"]

两者之间有什么区别

things.pop()

pop(things)

Python3.6处理它们的方式不同吗?两者之间有什么区别吗?

3 个答案:

答案 0 :(得分:3)

如果您要问有关pop的特定问题,答案很简单:没有名为pop的函数。因此,如果您尝试pop(things),则会得到NameError

当然,您始终可以编写自己的pop函数:

def pop(seq, *args, **kw):
    return seq.pop(*args, **kw)

现在,pop(things)things.pop()当然会做同样的事情。但是不同之处在于,前者调用您的pop函数,后者调用方法,而后者只是调用方法。


如果您要问有关Python是否支持UFCS ("uniform function calling syntax")的更一般的问题,那么f(x, a, b)之类的函数调用会自动转换为x.f(a, b) 1 如果有必要,那么答案是否定的,Python否。

其他一些语言也可以。 2 在C ++中,自由函数是这种类型的“接口的一部分”,并且C ++具有各种复杂的功能,例如Koenig查找,特殊的-以便操作员等可以完成这项工作,而UFCS是一种更简单且通常更易读的方式。

UFCS在动态类型的语言中意义不大,但一直有定期的提案建议将它添加为Python。例如,请参见this mailing list discussion

相反的方向,UMCS(“统一方法调用语法”),其中x.f(a, b)变成f(x, a, b),在{{1} }查找失败,这很容易通过x.f进行挂接(这很自然地适合Python的Smalltalk启发式动态查找)。还有funcall之类的库,如果您有兴趣的话可以使用(尽管我不知道任何可用于生产的解决方案)。


1。 …,或者也许是__getattr__。这些不是完全相同的东西,但是对于任何 normal 类型,例如type(x).f(x, a, b),它们将具有相同的效果(如blhsing's answer中所述),并且对于做一些奇怪的事情,使它们有所不同,我认为调用unbound方法可能更可能是您想要的。

2。也有人提议将其添加到C ++中,可以追溯到C ++ 0x时代。我认为当前版本是Stroustrop's N4174,这是一个不完整的调查/摘要,C ++ 17推迟了该版本的后续工作,但可以再次考虑。

答案 1 :(得分:2)

>>> things = ["Dog", "Zebra", "Cow"]
>>> things.pop()
'Cow'
>>> pop(things)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'pop' is not defined

所以,是的,有区别。我不知道你为什么会有所不同?

答案 2 :(得分:2)

pop不是内置的Python函数。在您的示例中,只有things.pop()有效。

另一方面,如果您要询问list.pop(things),则是的,它与things.pop()相同。

尽管list.pop(things)的可读性比things.pop()略低,因此一般不建议使用,但是list.pop在将其用作某些基于迭代器的操作的函数时可能会很有用。例如,以下内容为您提供列表的每个子列表的最后一项的列表:

>>> a=[[1, 2, 3],[9, 8, 7]]
>>> list(map(list.pop, a))
[3, 7]
>>>