20

スクリプトでこのコードを使用して、クロスプラットフォームの方法で、正確にどこから実行されているかを特定します。

SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

ものすごく単純。次にSCRIPT_ROOT、スクリプトの他の領域で使用して、すべてが適切に相対的であることを確認します。生成された実行可能ファイルが設定されていないため、py2exeを介して実行すると問題が発生し__file__、スクリプトが壊れます。これを修正または回避する方法を知っている人はいますか?

4

4 に答える 4

25

py2exe ドキュメント リファレンスは次のとおりです。関連項目は次のとおりです。

  • sys.executableexeファイルのフルパス名に設定されます。
  • の最初の項目sys.argvは実行可能ファイルのフル パス名で、残りはコマンド ライン引数です。
  • sys.frozen実行可能ファイルにのみ存在します。コンソール実行可能ファイルの場合は「console_exe」、コンソールなしの GUI 実行可能ファイルの場合は「windows_exe」、インプロセス dll サーバーの場合は「dll」に設定されます。
  • __file__は定義されていません (代わりに sys.argv[0] を使用することをお勧めします)

これらのドキュメントからは、「exe ファイル」と「実行可能ファイル」が同じものであるかどうか、したがってsys.executablesys.argv[0]が同じものであるかどうかは明らかではありません。前回、script.py と py2exe_executable.exe の両方で機能したコードを見ると、次のようなことがわかります。

if hasattr(sys, 'frozen'):
    basis = sys.executable
else:
    basis = sys.argv[0]
required_folder = os.path.split(basis)[0]

私が言うように、それはうまくいきましたが、なぜそれが必要だと思ったのか思い出せませんsys.argv[0]

basis手元のジョブ (そのディレクトリ内のファイルを読み取る) には、使用するだけで十分でした。より永続的な記録については、 のように分割しますos.path.realpath(basis)

更新実際にテストを行いました。当て推量と肘掛け椅子のポンティフィケーションを打ち負かします:-)

概要: sys.frozen を無視し、sys.executable を無視し、無条件に sys.argv[0] を使用します。

証拠:

=== foo.py ===

# coding: ascii
import sys, os.path
print 'sys has frozen:', hasattr(sys, 'frozen')
print 'using sys.executable:', repr(os.path.dirname(os.path.realpath(sys.executable)))
print 'using sys.argv[0]:',    repr(os.path.dirname(os.path.realpath(sys.argv[0]   )))

=== setup.py ===

from distutils.core import setup
import py2exe
setup(console=['foo.py'])

=== 結果 ===

C:\junk\so\py2exe>\python26\python foo.py
sys has frozen: False
using sys.executable: 'C:\\python26'
using sys.argv[0]: 'C:\\junk\\so\\py2exe' # where foo.py lives

C:\junk\so\py2exe>dist\foo
sys has frozen: True
using sys.executable: 'C:\\junk\\so\\py2exe\\dist'
using sys.argv[0]: 'C:\\junk\\so\\py2exe\\dist' # where foo.exe lives
于 2010-02-18T23:47:33.003 に答える
9

Py2exe は定義していません__file__: http://www.py2exe.org/index.cgi/Py2exeEnvironment

OP は、次の py2exe フレンドリー バージョンを要求しました。

SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

最良の答えは、python が exe でフリーズしているかどうかを判断することです。py2exe には、これに関するドキュメントがあります

import imp, os, sys

def main_is_frozen():
   return (hasattr(sys, "frozen") or # new py2exe
           hasattr(sys, "importers") # old py2exe
           or imp.is_frozen("__main__")) # tools/freeze

def get_main_dir():
   if main_is_frozen():
       return os.path.dirname(sys.executable)
   return os.path.dirname(os.path.realpath(__file__))

SCRIPT_ROOT = get_main_dir()

python はEAFPであるため、EAFPバージョンは次のとおりです ...

try:
   if sys.frozen or sys.importers:
      SCRIPT_ROOT = os.path.dirname(sys.executable)
except AttributeError:
   SCRIPT_ROOT = os.path.dirname(os.path.realpath(__file__))

乾杯!

于 2013-07-04T09:50:43.647 に答える
2

これを試して:

import os
import sys
os.path.realpath(os.path.dirname(sys.argv[0]))
于 2010-02-18T22:35:22.477 に答える
1

sys.argv[0]スクリプトまたは exe として実行されても同じ結果が得られるため、パスを取得する信頼できる方法です。ディレクトリを取得するにはos.path.dirname(sys.argv[0])

ファイルとexeの比較

于 2019-07-02T05:47:01.683 に答える