这两个 Python 语句有啥区别?

Posted

技术标签:

【中文标题】这两个 Python 语句有啥区别?【英文标题】:What is the difference in these two Python statements?这两个 Python 语句有什么区别? 【发布时间】:2014-04-25 15:00:22 【问题描述】:

我正在研究 Python 的 WiringPi-Python 的代码,我发现了几个这样的块:

def wiringPiSetup():
  return _wiringpi2.wiringPiSetup()
wiringPiSetup = _wiringpi2.wiringPiSetup

这对我来说有点令人费解,因为我认为:

def wiringPiSetup():
  return _wiringpi2.wiringPiSetup()

将产生与此完全相同的结果:

wiringPiSetup = _wiringpi2.wiringPiSetup

我知道第一个是声明一个新函数,第二个是对原始函数的引用,但在我所做的测试中,我发现它们是完全等价的。看这里:

>>> def a():
...     return 4
... 
>>> def a1():
...     return a()
... 
>>> a2 = a
>>> 
>>> a1()
4
>>> a2()
4

那么,当 WiringPi-Python 中的任何一个都足够时,为什么要同时使用它们呢?

顺便说一句:

我使用的是 Python 2.7.3 这是我看到的文件:here

【问题讨论】:

嗯?好问题,我不知道他们为什么要这么做。 尝试删除其中一个选项。它会破坏什么吗? 我注意到的第一件事是“这个文件是由swig自动生成的”,这可能解释了看似毫无意义的说法。不过,我从未使用过 SWIG,也不知道为什么它会生成这样的代码。 如果后来由于某种原因有人做了这样的事情会发生什么:_wiringpi2.wiringPiSetup = newfunc?如果你调用wiringPiSetup的函数版本,你可能会得到不同的结果。 @acushner 请记住,在 Python 中分配只是更改事物的名称。您的第一个示例会将_wiringpi2.wiringPiSetup 重命名为newfunc 并执行newfunc 所做的任何事情。如果您仍然有一个引用 wiringPiSetup 原始定义的名称,它将表现出原始行为。 【参考方案1】:

文件由SWIG生成。函数定义确实是“死代码”,因为您可以完全删除函数定义并保留赋值。

因为代码是自动生成的,所以代码效率有些低。 SWIG function that generates this code,声明:

if (Getattr(n, "feature:python:callback") || !have_addtofunc(n)) 
  /* If there is no addtofunc directive then just assign from the extension module (for speed up) */
  Printv(f_dest, name, " = ", module, ".", name, "\n", NIL);

所以第二个任务只是替换生成的 Python 函数以加快使用速度。

如果函数在生成时有额外的 Python 代码要添加(have_addtofunc() 在存在文档字符串、前置或附加值时为真),则不会生成替换行。

大概是保留了原始函数,以便自动完成工具可以使用函数签名。

【讨论】:

回答这个问题时差 3 秒。 很好的研究,你们俩! 谢谢,看来这是正确的。无论如何,我想知道这是否是让死代码放在那里的唯一原因。 @DWilches:看起来好像change was deliberate;它过去只是不生成功能。这是一个转换为 Git 的 SVN 提交,因此不会(轻松)检索到原始分支和该分支的提交。【参考方案2】:

此文件由SWIG 生成。从阅读SWIG Python generator soure code (emitFunctionShadowHelper) 看来,如果包装函数有一些文档字符串,代码生成器会创建一个包装函数,但是如果该函数没有任何文档字符串,那么代码生成器会发出一个简单的赋值语句。似乎“else”子句可能会添加到该函数中。

【讨论】:

以上是关于这两个 Python 语句有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

EntityDbContext SaveChanges :这两个代码有啥区别?

这两个代码片段有啥区别?

这两个视频有啥区别?

lxml 和 ElementTree 有啥区别?

这两个字符串有啥区别?

这两个片段有啥区别?