Python 3のexecfileに代わるものは何ですか?
-
22-07-2019 - |
質問
Python 3では、 execfile()
欠落している明らかな代替手段はありますか?
解決
他のヒント
ファイルを読み取り、自分でコードを実行するだけです。 2to3現在の置換
execfile("somefile.py", global_vars, local_vars)
as
with open("somefile.py") as f:
code = compile(f.read(), "somefile.py", 'exec')
exec(code, global_vars, local_vars)
(コンパイル呼び出しは厳密には必要ありませんが、ファイル名とコードオブジェクトを関連付けることで、デバッグが少し簡単になります。)
参照:
exec(open(" filename")。read())
は、 execfile(" filename")
の代替として頻繁に使用されますが、重要ではありません execfile
がサポートした詳細。
次のPython3.xの関数は、ファイルを直接実行するのと同じ動作をすることができる限り近いものです。これは、実行中の python /path/to/somefile.py
と一致します。
def execfile(filepath, globals=None, locals=None):
if globals is None:
globals = {}
globals.update({
"__file__": filepath,
"__name__": "__main__",
})
with open(filepath, 'rb') as file:
exec(compile(file.read(), filepath, 'exec'), globals, locals)
# execute the file
execfile("/path/to/somefile.py")
注:
- エンコードの問題を回避するためにバイナリ読み取りを使用します
- ファイルを閉じることを保証します(Python3.xはこれについて警告します)
-
__ main __
を定義します。一部のスクリプトはこれに依存して、モジュールとしてロードするかどうかをチェックします。if __name__ ==" __ main __"
- 例外メッセージには
__ file __
を設定する方が適切であり、一部のスクリプトは__ file __
を使用してそれらに関連する他のファイルのパスを取得します。 -
オプションのグローバルを取得& locals引数、
execfile
のようにインプレースで変更します-実行後に変数を読み戻すことで定義された変数にアクセスできます。 -
Python2の
execfile
とは異なり、これはデフォルトで現在のネームスペースを変更しません。そのためには、globals()
&を明示的に渡す必要があります。locals()
。
python-devで提案されているメーリングリスト最近では、 runpy モジュールが実行可能な代替手段になる可能性があります。そのメッセージからの引用:
https://docs.python.org/3/library/ runpy.html#runpy.run_path
import runpy file_globals = runpy.run_path("file.py")
execfile
には微妙な違いがあります:
-
run_path
は常に新しい名前空間を作成します。モジュールとしてコードを実行するため、グローバルとローカルに違いはありません(これがinit_globals
引数のみがある理由です)。グローバルが返されます。execfile
locals
およびglobals
のセマンティクスは、指定された場合、クラス定義内のローカルおよびグローバルに似ていました。 -
run_path
は、ファイルを実行できるだけでなく、eggsおよびディレクトリも実行できます(詳細については、ドキュメントを参照してください)。
これは、呼び出し側からグローバルとローカルを取得するため、より優れています。
import sys
def execfile(filename, globals=None, locals=None):
if globals is None:
globals = sys._getframe(1).f_globals
if locals is None:
locals = sys._getframe(1).f_locals
with open(filename, "r") as fh:
exec(fh.read()+"\n", globals, locals)
独自の関数を作成できます:
def xfile(afile, globalz=None, localz=None):
with open(afile, "r") as fh:
exec(fh.read(), globalz, localz)
本当に必要な場合...
ロードするスクリプトが実行するディレクトリと同じディレクトリにある場合、「インポート」仕事をしますか?
コードを動的にインポートする必要がある場合、組み込み関数 __ import __ および imp モジュールは、見る価値があります。
>>> import sys
>>> sys.path = ['/path/to/script'] + sys.path
>>> __import__('test')
<module 'test' from '/path/to/script/test.pyc'>
>>> __import__('test').run()
'Hello world!'
test.py:
def run():
return "Hello world!"
Python 3.1以降を使用している場合は、 importlib 。
ここに私が持っていたものがあります( file
は両方の例でソースコードを含むファイルへのパスに既に割り当てられています):
execfile(file)
次のように置き換えました:
exec(compile(open(file).read(), file, 'exec'))
お気に入りの部分:2番目のバージョンはPython 2と3の両方で問題なく動作します。つまり、バージョン依存のロジックを追加する必要はありません。
PEP-263エンコーディング宣言を使用している場合、上記のパターンは失敗することに注意してください それはasciiやutf-8ではありません。データのエンコードを見つけてエンコードする必要があります exec()に渡す前に正しく。
class python3Execfile(object):
def _get_file_encoding(self, filename):
with open(filename, 'rb') as fp:
try:
return tokenize.detect_encoding(fp.readline)[0]
except SyntaxError:
return "utf-8"
def my_execfile(filename):
globals['__file__'] = filename
with open(filename, 'r', encoding=self._get_file_encoding(filename)) as fp:
contents = fp.read()
if not contents.endswith("\n"):
# http://bugs.python.org/issue10204
contents += "\n"
exec(contents, globals, globals)
また、純粋なPythonソリューションではありませんが、IPythonを使用している場合(おそらくとにかく)、次のことができます。
%run /path/to/filename.py
どちらも簡単です。
私はここの初心者ですので、これを見つけたのなら幸運でしょう:
インタープリタープロンプトからスクリプトを実行しようとした後&gt;&gt;&gt;コマンドで
execfile('filename.py')
&quot; NameError:name 'execfile' is not defined&quot;私は非常に基本的な
を試しました import filename
うまくいきました:-)
これが役立つことを願っており、素晴らしいヒント、例、そして初心者の素晴らしいインスピレーションである、コメントを付けたコードの断片すべてに感謝します!
Ubuntu 16.014 LTS x64を使用しています。 Python 3.5.2(デフォルト、2016年11月17日、17:05:23) [GCC 5.4.0 20160609] Linuxの場合