私はpy2exeでコンパイルされたpythonプログラムを1台のサーバーマシンから多数のクライアントマシンで実行しています(すべてのマシンのネットワークドライブにマップされています.W :など)。
Windows XP 以降のマシンでは、これまでのところ、Python が W:\python23.dll を拾うという問題はありませんでした (はい、私は W98 との互換性のために Python 2.3.5 を使用しています)。次に、W:\zlib.pyd を使用して、os などのすべての .pyc ファイルを含む W:\library.zip を解凍します。これらはインポートされ、プログラムは問題なく実行されます。
この問題は、一部の Windows 98 SE マシンで発生しています (注: 一部の Windows 98 SE マシン、その他は明らかな問題なく動作するようです)。何が起こるかというと、プログラムは W: から実行され、W:\python23.dll が見つかったと思います (Python の ImportErrors が発生しているため、Python の import ステートメントを実行できる必要があります)。いくつかのことが機能しません:
1) W:\library.zip に .pyc ファイルの唯一のコピーが含まれている場合、
ZipImportError: can't decompress data; zlib not available
(W:\zlib.pyd が利用可能であり、同じネットワーク上の XP 以降のマシンで正常に動作することを考えるとナンセンスです)。
2) .pyc ファイルが py2exe によって python exe 内に実際にバンドルされている場合、または .exe と同じディレクトリに置かれている場合、または PYTHONPATH 変数の一部として設定される名前付きサブディレクトリに置かれている場合 (例: W:\pylib) )、取得しますImportError: no module named os
(os は、sys などの前にインポートされた最初のモジュールです)。
考えてみると、osがインポートされる前にsys.pathを検索できなかったのでしょうか?これらのインポートの順序を変更してみますが、私の疑問はまだ残っています:なぜこれは散発的な問題で、一部のネットワークでは機能し、他のネットワークでは機能しないのですか? また、実行する実行可能ファイル内にバンドルされているファイルを Python に強制的に検索させるにはどうすればよいでしょうか。私は稼働中の Windows 98 SE マシンにすぐにアクセスできますが、稼働していないマシン (私の顧客) には、毎朝店が開く前にしかアクセスできません。
前もって感謝します!
編集:さて、大きな一歩前進。PY2EXE_VERBOSE でデバッグした後、特定の W98SE マシンで発生する問題は、インポートを探すときに正しいパス構文を使用していないことです。まず、PYTHONPATH 環境変数を読み取っていないようです (PY2EXE_VERBOSE のように、私が認識していない py2exe 固有のものがある可能性があります)。
第 2 に、あきらめる前に 1 か所だけを検索します (ファイルが EXE 内にバンドルされている場合は、そこを検索します。そうでない場合は、library.zip を検索します)。
EDIT 2 : 実際、thisによると、Python インタープリターの sys.path と Py2exe 実行可能ファイルの sys.path には違いがあります。具体的には、sys.path contains only a single entry: the full pathname of the shared code archive.
何とか。フォールバックはありませんか?現在の作業ディレクトリでさえありませんか?PATH に追加してみW:\
ますが、py2exe はシステム ライブラリを検索するための標準に準拠していないため、機能しません。
さて、興味深い点です。atexit、os などをロードしようとするパスは次のとおりです。
W:\\library.zip\<module>.<ext>
library.zip の後の 1 つのスラッシュですが、ドライブ文字の後の 2 つのスラッシュに注意してください (これが意図されていて動作する場合は、誰かが私を修正してください)。これが文字列リテラルの場合、スラッシュが二重にされていないため、(無効な) エスケープ シーケンスとして読み取られ、生の文字が出力されます (W:\library.zipos.pyd, W:\library.zipos.dll, ...
スラッシュの代わりに表示されます)。文字列リテラルでない場合、二重スラッシュは自動的にノルムパス化されない可能性があり (そうあるべきです)、二重スラッシュはモジュール ローダーを混乱させます。私が言ったように、set PYTHONPATH=W:\\library.zip\\
その変数を無視するという理由だけではできません。
プログラムの開始時に sys.path.append を使用する価値があるかもしれませんが、特に古い OS の 1 つの構成で問題が発生するため、ハードコーディング モジュール パスは絶対的な最後の手段です。
何か案は?私は 1 つを持っていsys.path
ますos
。もう 1 つは、追加os.getenv('PATH')
するかos.getenv('PYTHONPATH')
、sys.path に追加することです... 再び、os
モジュールが必要です。モジュールも初期化に失敗するsite
ため、.pth ファイルを使用できません。
また、最近、プログラムの開始時に次のコードを試しました。
for pth in sys.path:
fErr.write(pth)
fErr.write(' to ')
pth.replace('\\\\','\\') # Fix Windows 98 pathing issues
fErr.write(pth)
fErr.write('\n')
しかし、それは linecache.pyc やその他のものをロードすることはできません。見た目からは実際にこれらのコマンドを実行することはできません。sys.path を動的に変更するために linecache を必要としない組み込み機能を使用する方法はありますか? それとも、正しい sys.path をハードコーディングする必要がありますか?