【问题标题】:Python 3.4 imports ./xml.py on exception by default?默认情况下,Python 3.4 在异常时导入 ./xml.py?
【发布时间】:2016-01-03 13:00:52
【问题描述】:

由于某种奇怪的原因,如果发生异常,我的 Python 解释器会执行文件 ./xml.py。我完全不知道为什么会发生这种情况 - 我绝对不希望这种情况发生。

我已经建立了一个新目录,其中包含一个名为 xml.py 的文件,其中仅包含“print("Hello xml.py")”行。启动 python3 后,我在解释器提示符处输入“a”。这应该向我显示一个简单的 NameError,因为 a 当然没有定义,而是打印“Hello xml.py”(即执行 ./xml.py)和一堆其他错误,然后才将 NameError 转储到屏幕上:

$ python3
Python 3.4.3 (default, Mar 26 2015, 22:03:40) 
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a
Hello xml.py
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
Error in sys.excepthook:
Traceback (most recent call last):
  File "<frozen importlib._bootstrap>", line 2218, in _find_and_load_unlocked
AttributeError: 'module' object has no attribute '__path__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 63, in apport_excepthook
    from apport.fileutils import likely_packaged, get_recent_crashes
  File "/usr/lib/python3/dist-packages/apport/__init__.py", line 5, in <module>
    from apport.report import Report                                                                                                                         
  File "/usr/lib/python3/dist-packages/apport/report.py", line 15, in <module>                                                                               
    import xml.dom, xml.dom.minidom                                                                                                                          
ImportError: No module named 'xml.dom'; 'xml' is not a package                                                                                               

Original exception was:                                                                                                                                      
Traceback (most recent call last):                                                                                                                           
  File "<stdin>", line 1, in <module>                                                                                                                        
NameError: name 'a' is not defined 

删除xml.py后一切恢复正常:

$ rm xml.py 
$ python3
Python 3.4.3 (default, Mar 26 2015, 22:03:40) 
[GCC 4.9.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> 

简单而简短的问题:这里到底发生了什么?

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    这些位是线索:

    Error in sys.excepthook:
    

    Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 63, in apport_excepthook
        from apport.fileutils import likely_packaged, get_recent_crashes
      File "/usr/lib/python3/dist-packages/apport/__init__.py", line 5, in <module>
        from apport.report import Report                                                                                                                         
      File "/usr/lib/python3/dist-packages/apport/report.py", line 15, in <module>                                                                               
        import xml.dom, xml.dom.minidom                                                                                                                          
    ImportError: No module named 'xml.dom'; 'xml' is not a package
    

    apportpart of Ubuntu,而且,无论好坏,似乎都试图捕获所有 Python 异常(使用 sys.excepthook)并处理它们。这样做时,它会尝试导入 xml 包 (part of the Python standard library)。因为您已使用本地文件为该包起别名,所以它会导入该文件,找不到所需的包,并引发另一个异常。

    您可以将您的 xml.py 重命名为不为标准库中的包起别名的名称,或者将此行放在程序执行的早期以禁用 apport 的异常挂钩:

    # reassign sys.excepthook to its initial value
    sys.excepthook = sys.__excepthook__
    

    【讨论】:

    • 感谢您的解释!
    【解决方案2】:

    Apport 是 Ubuntu 附带的程序。该程序的主要目的是检测程序崩溃并报告它们。每当发生异常时,Appor 都会尝试使用异常挂钩来处理它。这里有一个关于这个主题的错误报告:https://bugs.launchpad.net/ubuntu/+source/apport/+bug/109955

    现在正在发生这种情况:当您尝试在控制台中输入 a 时,会发生以下错误:

    Traceback (most recent call last):                                                                                                                           
      File "<stdin>", line 1, in <module>                                                                                                                        
    NameError: name 'a' is not defined 
    

    Apport 有一个异常钩子集,在这个异常上被调用。 Appport 继续并尝试报告它。在这个过程中,它会尝试从标准库中导入一个名为xml 的包。但是,您将文件命名为 xml.py,因此它会隐藏标准库中的 xml 包。所以导入失败:

    Traceback (most recent call last):
      File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 63, in apport_excepthook
        from apport.fileutils import likely_packaged, get_recent_crashes
      File "/usr/lib/python3/dist-packages/apport/__init__.py", line 5, in <module>
        from apport.report import Report                                                                                                                         
      File "/usr/lib/python3/dist-packages/apport/report.py", line 15, in <module>                                                                               
        import xml.dom, xml.dom.minidom                                                                                                                          
    ImportError: No module named 'xml.dom'; 'xml' is not a package    
    

    请注意,xml 是标准库中的一个包(例如,它有一个 __init__.py)。但是,您创建了一个模块(xml.py 文件)。所以它不能从中导入xml.dom

    删除xml.py 后它工作正常,因为工作目录中不再有一个模块会影响标准目录中的模块。

    禁用 Appor: 如果 apport 异常处理让您烦恼,您可以在此线程之后禁用它:https://askubuntu.com/questions/93457/how-do-i-enable-or-disable-apport - 但是,这通常会禁用错误报告,我不建议这样做。

    【讨论】:

    • 感谢您的解释!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 2020-09-25
    • 2010-12-02
    • 2012-11-24
    • 1970-01-01
    相关资源
    最近更新 更多