python2中的“from builtins import*”和super():错误的实践?

2024-03-28 18:37:42 发布

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

我正试着把我的Python3包向后移植到Python2。我用了pasteurize,一切正常。我注意到它从builtins导入了一些内容,包括strint和{}。我想知道从builtins导入所有内容是否安全。是的,我知道原则上asterisk import is considered bad practice是因为它扰乱了当前的名称空间,不能清楚地说明导入了什么并重写了您不想导入的名称。但是,尤其是在builtins时,不是所有这些都已经作为名称存在,可以安全地导入并且不应该破坏任何东西吗?在

另外,如果在Python2代码中使用superfrombuiltins,那么将其称为Python3的super是安全的吗?是否存在可能与Python2断裂的边缘情况?在

from builtins import * # is this frowned upon?
from future import standard_library
standard_library.install_aliases()

class Foo(object):
    def __init__(self):
        super().__init__() # is this always safe in python 2?

编辑1:为了澄清,Python2builtins来自future,而不是Python3中的内置模块。在

编辑2:有些人建议不带参数的调用super永远不会有效,而从builtins导入也没什么区别。显然这是错误的。在

^{pr2}$

Tags: fromimport名称编辑内容initislibrary
2条回答

I noticed that it imported a few stuff from builtins including str, int and super

您不需要从bultins中import东西,因为它们都是默认导入的。在

is it safe to call it as Python3's super with no arguments?

否-super不向后兼容,因此必须将参数传递给那里:

Python 3:

class Foo(object):
    def __init__(self):
        super().__init__()

Python 2:

^{pr2}$

这个super是python3super的一个重新实现,但是不要期望它像python3super那样高效。在

在python3中,编译器作弊,每当它看到函数中引用的名称super,它就会自动向函数添加一个名为__class__的单元变量。super函数使用__class__来弥补没有传递给它的参数。您可以通过执行以下操作来看到这一点:

class X:
    def f(self):
        super
        return __class__

assert X().f() is X
assert X.f.__closure__[0].cell_contents is X

__class__只定义一次(当函数第一次编译时)+,因此super的查找非常快速。在

另一方面,每次都需要深入MRO(和任何decorator),以确定{}的类型和定义函数的类型。它似乎很适合后移植python3(可能是它存在于future.builtins中的原因)。但是您应该坚持使用标准的python2super,因此阅读您代码的人对此并不感到惊讶。

实现:(取自https://github.com/rfk/magicsuper/blob/master/magicsuper/_super.py(由future.builtins.newsuper记录)

^{pr2}$

相关问题 更多 >