使用Pycharm调试PyQt gui时出现奇怪的错误

时间:2017-03-09 20:58:37

标签: python debugging pyqt pycharm pydev

我一直在使用PyCharm在PyQt中调试我的gui。到目前为止,这已经非常成功,直到我在尝试调试我的gui时遇到了一个奇怪的错误。我已经在脚本的开头和各个点设置了断点,但程序没有机会达到这一点。我也尝试删除所有断点并运行调试但得到相同的结果。完整的追溯是:

func updateTeam(teamID: Int) {
    startConnection {NSArray, Int in
        //Do things with NSArray
    }
}

func startConnection(completion: (NSArray, Int) -> Void) {
    let url = URL(string: "http://www.example.com/path")
    var request : URLRequest = URLRequest(url: url!)
    request.httpMethod = "POST"
    let postString = "a=\(Int(teamInput.text!)!)"
    request.httpBody = postString.data(using: .utf8)

    let dataTask = URLSession.shared.dataTask(with: request) {
        data,response,error in
        print("anything")
        do {
            if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
                self.teamResult = jsonResult
                print(jsonResult)
            }
        } catch let error as NSError {
            print(error.localizedDescription)
        }

    }
    dataTask.resume()

    completion(NSArray(object: teamResult), Int(teamInput.text!)!)
}

有谁知道导致此错误的原因以及如何解决?当我正常运行代码(没有调试)时,我不会遇到任何这些错误。

2 个答案:

答案 0 :(得分:18)

我遇到了同样的问题,我花了一段时间,但我发现了一个适合我的解决方案。我相信会发生什么,是调试器正在目录_pydevd_bundle.pydevd_cython中寻找模块code。但是,因为您从自己的code目录运行脚本,调试器会检查您的文件夹,看到它们不是模块,并抛出错误。这可以解释为什么删除__init__.py有效,因为调试器不会再混淆这两个目录。

因此,将代码目录重命名为其他内容,应解决问题并让您保留init文件。

答案 1 :(得分:1)

我最近遇到了这个问题(在研究[SO]: zipfile.BadZipFile: Bad CRC-32 when extracting a password protected .zip & .zip goes corrupt on extract (@CristiFati's answer)时)。注意,除非另有限制,否则我将代码段命名为 code.py

Python

根据[Python 3.Docs]: Modules - The Module Search Path强调是我的):

  

导入名为 spam 的模块时,解释器首先搜索具有该名称的内置模块。如果找不到,它将在变量sys.path给定的目录列表中搜索名为spam.py的文件。 sys.path从以下位置初始化:

     
      
  • 包含输入脚本的目录(如果未指定文件,则为当前目录)
  •   
  • PYTHONPATH(目录名称列表,语法与shell变量 PATH 相同)。
  •   
  • 与安装有关的默认设置。
  •   

小样:

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q042705279]> set py
PYTHONPATH=E:\Work\Dev\Utils

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q042705279]> dir /b

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q042705279]> "e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe"  -c "import code;print(code)"
<module 'code' from 'c:\\Install\\x64\\Python\\Python\\03.06.08\\Lib\\code.py'>

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q042705279]> echo. 2>code.py


[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q042705279]> dir /b
code.py

[cfati@CFATI-5510-0:e:\Work\Dev\StackOverflow\q042705279]> "e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe"  -c "import code;print(code)"
<module 'code' from 'e:\\Work\\Dev\\StackOverflow\\q042705279\\code.py'>

(在正常情况下)可以看到,如果在 cwd 中找到了模块 code (也适用于软件包),则会加载该模块从那里。
code 模块( code.py )不是随机选择的(请阅读下一节)。检查[Python 3.Docs]: code - Interpreter base classes以获得有关标准 Python 库的一部分的详细信息。

PyCharm

运行 PyCharm 配置时, PyCharm (简体)将在配置的脚本上启动项目解释器。这可行。就我而言:

"E:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" "E:/Work/Dev/StackOverflow/q042705279/code.py"

但是,当调试相同的配置时,情况会有些复杂。简化版:

  • pydevd 创建的服务器将执行目标脚本
  • PyCharm IDE 连接到该服务器以获取输出

同样,在我的情况下是:

"E:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" "C:\Install\x64\JetBrains\PyCharm Community Edition\AllVers\helpers\pydev\pydevd.py" --multiproc --qt-support=auto --client 127.0.0.1 --port 45931 --file "E:/Work/Dev/StackOverflow/q042705279/code.py"

关键点位于 pydevconsole.py 的开头(在异常回溯中提到):

try:
    from code import InteractiveConsole
except ImportError:
    from _pydevd_bundle.pydevconsole_code_for_ironpython import InteractiveConsole

因此,它尝试加载 InteractiveConsole ,该加载(显然)会失败。
显然, code 模块特定于 C Python 。没有它意味着它是另一个发行版(请检查[Python]: Alternative Python Implementations)。
IPython 替代选项(默认选中)包含不符合 Python 3 (从语法上)兼容的脚本(当前IronPython位于< em> v 2.7 .9 )。请注意,这是在到达用户代码之前发生的。
将解释器切换为 Python 2 也无济于事,这将通过这一点,但是稍后它还将尝试设置交互式控制台,这将失败。

结论

  • 您的sys.path中没有任何名为 code 的模块/软件包(在 Python 的标准路径之前)
  • 显然 pydevd.py 还有其他参数,但是快速检查并没有发现使用它们解决该问题的任何可能性
  • 通过更改工作目录,我能够成功调试 code.py 文件(来自 PyCharm )从配置设置。但是,我认为这是(lam)解决方法( gainarie ),对于复杂的设置,它可能甚至无法工作