【问题标题】:Why it failed without import in python为什么没有在python中导入就失败了
【发布时间】:2015-05-20 11:47:55
【问题描述】:

我是新手,刚开始学习 Python 编程:

import sys
from PyQt5 import QtWidgets

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    mainWindow = QtWidgets.QMainWindow()
    mainWindow.show()

    sys.exit(app.exec_())

当我运行上述代码时,一切正常。但是当我运行下面的代码时,它会失败并显示以下错误消息: app = PyQt5.QtWidgets.QApplication(sys.argv) AttributeError:“模块”对象没有属性“QtWidgets”

import sys
import PyQt5
if __name__ == "__main__":
    app = PyQt5.QtWidgets.QApplication(sys.argv)

    mainWindow = PyQt5.Qtwidgets.QmainWindow()
    mainWindow.show()

    sys.exit(app.exec_())

顺便说一下,我的 Python 版本是 2.7,我使用的是 Qt5 库,我的操作系统是 OpenSUSE 13.2,当然是 Linux 的发行版。

【问题讨论】:

  • QtWidgets 是在PyQt5__init__.py 中定义的类。见stackoverflow.com/questions/582723/…
  • 我刚刚阅读了您发送的帖子。但是还是一头雾水,要不要解释清楚?谢谢。 @塞尔丘克

标签: python import pyqt5 qtwidgets


【解决方案1】:

PyQt5 部分只是为一组模块提供了一个命名空间。它本身不包含任何内容,因此您不能直接从中导入任何内容。

这是一个深思熟虑的设计决定,这样做是有充分理由的。包中可能总共有 30 个或更多模块,因此每次导入 PyQt5 本身时加载它们全部将是一笔沉重的前期成本。因此,我们的目的是只支付加载您实际需要的模块的成本。

但是,有时您确实想要一次加载所有模块。例如,在 python 交互式会话中进行实验时能够做到这一点会非常方便。事实上,PyQt 提供了一个特殊的模块来做这件事:

>>> from PyQt5 import Qt
>>> Qt.QWidget
<class 'PyQt5.QtWidgets.QWidget'>
>>> Qt.QObject
<class 'PyQt5.QtCore.QObject'>
>>> Qt.QNetworkCookie
<class 'PyQt5.QtNetwork.QNetworkCookie'>

【讨论】:

    【解决方案2】:

    Qtwidgets 文件是在PyQt5 目录中编译的.so 文件,与所有模块一样,__init__.py 文件中没有导入,因此您需要使用 from ...

    py3 目录中使用cython 编译文件test1.cpython-34m.so 和空__init.__py 的示例表现出相同的行为:

    In [1]: import py3
    
    In [2]: py3.test1
    ---------------------------------------------------------------------------
    AttributeError                            Traceback (most recent call last)
    <ipython-input-2-9aa45b2a49b6> in <module>()
    ----> 1 py3.test1
    
    AttributeError: 'module' object has no attribute 'test1'
    
    In [3]: from py3 import test1
    In [4]: test1.foo()
    Out[4]: 100
    

    PyQt5中的文件如下:

    /usr/lib/python3/dist-packages/PyQt5$ ls
    __init__.py
    __pycache__
    _QOpenGLFunctions_2_0.cpython-34m-x86_64-linux-gnu.so
    QtCore.cpython-34m-x86_64-linux-gnu.so
    Qt.cpython-34m-x86_64-linux-gnu.so
    QtDBus.cpython-34m-x86_64-linux-gnu.so
    QtDesigner.cpython-34m-x86_64-linux-gnu.so
    QtGui.cpython-34m-x86_64-linux-gnu.so
    QtHelp.cpython-34m-x86_64-linux-gnu.so
    QtNetwork.cpython-34m-x86_64-linux-gnu.so
    QtOpenGL.cpython-34m-x86_64-linux-gnu.so
    QtPrintSupport.cpython-34m-x86_64-linux-gnu.so
    QtTest.cpython-34m-x86_64-linux-gnu.so
    QtWidgets.cpython-34m-x86_64-linux-gnu.so
    uic
    

    使用cat可以看到__init__.py中没有导入:

    $:/usr/lib/python3/dist-packages/PyQt5$ cat __init__.py 
    # Copyright (c) 2014 Riverbank Computing Limited <info@riverbankcomputing.com>
    # 
    # This file is part of PyQt5.
    # 
    # This file may be used under the terms of the GNU General Public License
    # version 3.0 as published by the Free Software Foundation and appearing in
    # the file LICENSE included in the packaging of this file.  Please review the
    # following information to ensure the GNU General Public License version 3.0
    # requirements will be met: http://www.gnu.org/copyleft/gpl.html.
    # 
    # If you do not wish to use this file under the terms of the GPL version 3.0
    # then you may purchase a commercial license.  For more information contact
    # info@riverbankcomputing.com.
    # 
    # This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    # WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
    

    因此,由于__init__.py 中没有导入,当您尝试使用 PyQt5.Qtwidgets 时,您会收到错误,因为模块显然没有属性。

    如果您在__init__.py 中添加了类似from . import QtWidgets 的内容,那么您可以使用import PyQt5 PyQt5.QtwidgetsPyQt5.Qtwidgets 在您从packageQtwidgets 时也可以使用空白初始化/强>PyQt5

    当你import PyQt5你时,你可以看到你实际上有一个模块:

    In [6]: import PyQt5
    
    In [7]: type(PyQt5)
    Out[7]: module
    

    因此,真正的区别以及您看到输出的原因是您尝试从第二个示例中的 module 和第一个示例中的 package 导入。

    【讨论】:

    • 哦,我明白了。但是如果我先import PyQt5.QWidgets,然后window = QWidgets.QMainWindow(),会发生什么?我现在在街上。也许我可以在家里做这个实验。非常感谢。
    • 你需要使用 PyQt5.QWidgets.QMainWindow()
    猜你喜欢
    • 1970-01-01
    • 2020-05-26
    • 2012-09-16
    • 2016-04-20
    • 2018-12-25
    • 2018-10-14
    • 1970-01-01
    • 2022-11-29
    • 2011-06-16
    相关资源
    最近更新 更多