我正在尝试追踪错误的原因:https://github.com/numba/numba/issues/3027
似乎(对于一些numba用户,但不是全部用户)
import sys
import numba
@numba.njit
def some_func(begin1, end1, begin2, end2):
if begin1 > begin2: return some_func(begin2, end2, begin1, end1)
return end1 + 1 >= begin2
sys.stdout = sys.stderr
x = id(sys.stdout)
some_func(0,1,2,3)
y = id(sys.stdout)
assert x==y # Fail
sys.stdout的值在调用somefunc之前和之后不同。我想知道这是否是因为:
似乎很难知道,因为如果调用reload,分配给模块命名空间的变量在重新加载后仍然存在,除非它们被模块本身重新初始化:
import sys
sys.stdout = None
sys.zzz = 123
sys = reload(sys)
sys.stderr.write("sys.stdout = {}\n".format(sys.stdout)) # Reset to file object
sys.stderr.write("sys.zzz = {}\n".format(sys.zzz)) # Surprise success!
sys.stderr.flush()
答案 0 :(得分:2)
虽然非常不满,some Python 2 code reloads sys
to restore the sys.setdefaultencoding()
function。这几乎总是造成这个问题的原因。
因此,您可以通过检查sys
属性来检测setdefaultencoding
已重新加载:
if hasattr(sys, 'setdefaultencoding'):
# sys was reloaded!
这只适用于Python 2.或者您可以使用额外字段扩充sys.flags
struct sequence:
from collections import namedtuple
import sys, re
_sys_flags_fields = re.findall('(\w+)=\d', repr(sys.flags))
_sys_flags_augmented = namedtuple('flags', _sys_flags_fields + ['sys_not_reloaded'])
sys.flags = _sys_flags_augmented(*sys.flags + (1,))
之后你可以测试:
if not getattr(sys.flags, 'sys_not_reloaded', 0):
扩充sys.flags
比大多数其他sys
操作更安全,因为第三方代码可能依赖于已记录的sys
属性和方法,而和< / em>它也可以在Python 3上运行。
您可以通过打包sys
/ __builtin__.reload
/ importlib.reload
来阻止 imp.reload
重新加载:
try:
# Python 2
import __builtin__ as targetmodule
except ImportError:
# Python 3.4 and up
try:
import importlib as targetmodule
targetmodule.reload # NameError for older Python 3 releases
except (ImportError, AttributeError):
# Python 3.0 - 3.3
import imp as targetmodule
from functools import wraps
def reload_wrapper(f):
@wraps(f)
def wrapper(module):
if getattr(module, '__name__', None) == 'sys':
raise ValueError('sys should never be reloaded!')
return f(module)
return wrapper
targetmodule.reload = reload_wrapper(targetmodule.reload)
您可以使用warnings
module或其他一些机制来记录或警告sys
正在重新加载的事实,而不是引发异常;你可能希望include the caller加入这样的警告。
尽早执行上述模块,以确保可以通过将其插入sitecustomize
模块或从.pth
文件中触发来捕获执行此操作的代码安装到site-packages
目录中。 .pth
文件中以import
开头的任何行都是executed as Python code by the site.py
module at Python startup,因此此类文件中包含以下内容:
import yourpackage.sysreload_neutraliser
会在Python启动时注入导入。