7

PythonとPySideを使用してかなり複雑なアプリケーションを構築しています。いよいよリリースの日が近づいているので、このアプリケーションをexeファイルとしてビルドしたいと思います。

しかし、私は私の手に奇妙な問題を抱えています。私は過去にPyInstaller(ちなみにバージョン2を使用)を使用しましたが、これが発生したことはありません。

基本的に、フラグを使用してアプリケーションをビルドすると、--console正常に動作しますが、コンソールウィンドウが開きます。ウィンドウフラグ()を使用してアプリケーションをビルドすると、-w正常に動作しません。それは始まり、すべてですが、これらすべての奇妙なグリッチがあります。たとえば、テキストファイルをロードするとBadFileDescriptorエラーが発生することが多く(コンソールモードでは発生しません)、特定のタスクを実行した後にアプリケーションがクラッシュします。さらに悪いことに、タスクはループであり、最初は正常に実行されますが、再び機能し始めるとクラッシュします。

minidumpファイルを見ると、QtGui4.dllファイルのメモリアクセス違反に関するエラーがありました。繰り返しますが、これはコンソールモードでは発生しません。

誰かアイデアはありますか?

4

1 に答える 1

9

エラーとその結果としてのメモリアクセス違反は、ウィンドウモードのアプリケーションが固定サイズのバッファであるBadFileDescriptorという事実によって引き起こされます。stdoutしたがって、をstdout使用して、printまたはsys.stdout直接に書き込みを行っている場合は、しばらくするとこれらのエラーが表示されます。

これは次の方法で修正できます。

  1. 上の書き込みを削除/コメントアウトstdout
  2. loggingstdoutに印刷する代わりに使用する
  3. stdoutアプリケーションの実行の開始時にリダイレクトします。loggingこれは、デバッグステートメントをに移動する方が良い選択だと思いますが、変更する必要のあるコードが少ないソリューションです。

リダイレクトstdoutするには、次の種類のコードを使用できます。

import sys
import tempfile
sys.stdout = tempfile.TemporaryFile()
sys.stderr = tempfile.TemporaryFile()

プログラムを実行する直前。カスタムオブジェクトを使用して、出力を「ログ」ファイルなどに配置することもできます。重要なことは、出力が固定サイズのバッファーをいっぱいにしないことです。

たとえば、次のようなことを実行して、loggingコードをあまり変更せずにモジュールを利用できるようにすることができます。

import sys
import logging

debug_logger = logging.getLogger('debug')
debug_logger.write = debug_logger.debug    #consider all prints as debug information
debug_logger.flush = lambda: None   # this may be called when printing
#debug_logger.setLevel(logging.DEBUG)      #activate debug logger output
sys.stdout = debug_logger

このアプローチの欠点は、各行に対してprintより多くの呼び出しを実行することです。stdout.write

>>> print 'test'
DEBUG:debug:test
DEBUG:debug:

必要に応じて、「フルライン」でのみwrite呼び出す実際の関数を作成するこの種の動作をおそらく回避できます。the_logger.debug

printとにかく、これらの種類のソリューションは一時的なものであり、 sをへの呼び出しに移植する前にのみ使用する必要があると思いますlogging.debug

(明らかに、ロガーはstdoutエラーを回避するためではなく、ファイルに書き込む必要があります。)

于 2012-11-17T12:49:27.280 に答える