gpt4 book ai didi

python - "from builtins import *"和 python2 中的 super() : bad practice?

转载 作者:太空宇宙 更新时间:2023-11-03 21:03:53 25 4
gpt4 key购买 nike

我正在尝试将我的 Python3 包向后移植到 Python2。我使用了巴氏灭菌法,一切正常。我注意到它从 builtins 导入了一些东西,包括 strintsuper。我想知道从 builtins 导入所有内容是否安全。是的,原则上我知道asterisk import is considered bad practice因为它扰乱了当前的命名空间,无法清楚地说明导入的内容和覆盖您不打算导入的名称。但是,特别是对于 builtins 来说,它们不是都已经作为名称存在、可以安全导入并且不会破坏任何内容吗?

此外,如果在 Python2 代码中使用来自 builtinssuper ,将其称为不带参数的 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:只是为了澄清一下,对于 Python2 builtins 来自 future 并且不是 Python3 中的内置模块。

编辑 2:有些人建议不带参数调用 super 永远 工作,并且从 builtins 导入> 没有区别。显然这是错误的。

from __future__ import print_function

class Foo(object):
def __init__(self, x):
self.x = x

class Bar(object):
def __init__(self, x):
self.x = x + 1

class Baz(Bar, Foo):
def __init__(self, x):
super().__init__(x)

try:
b = Baz(1)
except TypeError as e:
# this will only happen in Python 2
print("Didn't work: {}; trying with builtins.super".format(str(e)))
from builtins import super
b = Baz(1) # this now works in Python 2.7 too
print(b.x)

最佳答案

这个 super 是 Python 3 super 的重新实现,可以工作,但不要期望它像 Python 3 super 一样高效。

在 Python 3 中,编译器会作弊,每当它看到函数中引用的名称 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 的查找非常快。

另一方面,

newsuper 每次都需要深入了解 MRO(以及任何装饰器),以找出 self 的类型以及该函数被定义为1。 它似乎适合向后移植 Python 3(这可能是它存在于 future.builtins 中的原因)。 但是您应该坚持使用标准 Python 2 super,这样阅读您代码的人就不会对此感到惊讶。

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

def super(typ=_SENTINEL, type_or_obj=_SENTINEL, framedepth=1):
'''Like builtin super(), but capable of magic.
This acts just like the builtin super() function, but if called
without any arguments it attempts to infer them at runtime.
'''
# Infer the correct call if used without arguments.
if typ is _SENTINEL:
# We'll need to do some frame hacking.
f = sys._getframe(framedepth)

try:
# Get the function's first positional argument.
type_or_obj = f.f_locals[f.f_code.co_varnames[0]]
except (IndexError,KeyError,):
raise RuntimeError('super() used in a function with no args')

try:
# Get the MRO so we can crawl it.
mro = type_or_obj.__mro__
except AttributeError:
try:
mro = type_or_obj.__class__.__mro__
except AttributeError:
raise RuntimeError('super() used with a non-newstyle class')

# A ``for...else`` block? Yes! It's odd, but useful.
# If unfamiliar with for...else, see:
#
# http://psung.blogspot.com/2007/12/for-else-in-python.html
for typ in mro:
# Find the class that owns the currently-executing method.
for meth in typ.__dict__.itervalues():
# Drill down through any wrappers to the underlying func.
# This handles e.g. classmethod() and staticmethod().
try:
while not isinstance(meth,FunctionType):
try:
meth = meth.__func__
except AttributeError:
meth = meth.__get__(type_or_obj)
except (AttributeError, TypeError):
continue
if meth.func_code is f.f_code:
break # Aha! Found you.
else:
continue # Not found! Move onto the next class in MRO.
break # Found! Break out of the search loop.
else:
raise RuntimeError('super() called outside a method')

# Dispatch to builtin super().
if type_or_obj is not _SENTINEL:
return _builtin_super(typ,type_or_obj)
return _builtin_super(typ)

关于python - "from builtins import *"和 python2 中的 super() : bad practice?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55554209/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com