如何在Python中抑制SyntaxWarning?

3

如何在Python中禁止SyntaxWarning?

以下是生成警告的代码行。

def myfunction():
    from myimportfile import *

请注意:
1. 在函数外导入文件不是一个选项。虽然导入可以正常工作,但它仍然会抛出SyntaxWarning警告。
2. warnings.simplefilter('ignore') 不起作用,因为警告是在代码实际运行之前生成的。
例如,
 def myfunction():
    print 'trace 1'
    from myimportfile import *
    print 'trace 2'

将输出

SyntaxWarning  
trace1  
trace2  

而不是

trace1  
SyntaxWarning  
trace2  

那么,我该如何禁用这个警告呢?
并且是否可能仅针对这行代码禁用警告?


2
你的Python版本是什么? 此外,以这种方式导入并不是最好的选择。最好在代码文件顶部导入。 - inspectorG4dget
1
那个警告的原因就是,正如它所说的那样,“只允许在模块级别导入*”。这是Python的后期版本中的一个错误。它还可能会极大地扩大函数的本地变量,这是一件不好的事情。为什么你不能只是使用from myimportfile import a, b或者import myimportfile并使用限定名称,或者将导入移动到模块级别呢? - abarnert
1个回答

0
你所尝试的不仅是一个坏主意,而且是非法的。正如文档所说:

使用带星号的from形式只能出现在模块范围内。如果在函数中使用通配符导入形式-import *-并且该函数包含或是嵌套块以自由变量形式存在,则编译器将引发SyntaxError。

在过渡版本中(仅凭记忆,我认为这是2.6、2.7和3.0,但请别引用我的话),该错误可能会变成警告。但如果您升级到较新的版本,或者可能只是使用同一版本的不同实现,那么你将会得到一个实际的错误。(对于较新版本:在CPython 3.3中肯定会出现错误。对于相同版本的不同实现:我测试了一个PyPy 1.9.0 beta和PyPy 1.9.0 final,它们都实现了Python 2.7;beta版打印出3个警告,然后引发异常,最终版在屏幕上水平散布3个警告,然后打印出3个正常警告。)

如果可能的话,您应该执行以下操作之一:

  • 将导入移至模块级别。
  • 使用from myimportfile import foo, bar 而不是 *
  • import myimportfile 然后使用合格名称使用所有内容。

如果你一定要将myimportfile中的所有内容导入到你的函数的locals作用域中,你最好想出一个巧妙的方法来完成这个任务,而不是想出一个绕过警告的巧妙方式。例如:

import myimportfile
locals().update(myimportfile.__dict__)

这个简单的版本可能没有完全相同的效果,但你可以尽可能接近。例如,要进行通常的限制,请过滤 name in myimportfile.__all__ (如果存在),或者 not name.startswith('_') or name.startswith('__') and name.endswith('__')。或者,如果您使用的是3.1或更高版本,请使用 importlib 而不是手动执行。


5
这个回答和问题完全不相关。问题不是关于修复代码的,而是关于抑制警告。这尤其重要,因为在开发阶段可能是无害甚至有益的警告,在最终用户使用时会成为巨大的痛点,特别是如果程序输出被算法地解析的话。 - Vladimir Nikishkin
这并没有什么“非法”的。在实际情况下,有些情况是有意义的。也许OP的例子不是最好的,但可以想象一下有一个测试来确保可以导入模块中的所有内容。 - Pithikos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接