.pycファイルを回避する方法


268

コンパイルされた.pycファイルを生成せずにPythonインタープリターを実行できますか?

回答:


288

「Pythonの2.6の新機能-通訳の変更」

-BスイッチをPythonインタープリターに提供するか、インタープリターを実行する前にPYTHONDONTWRITEBYTECODE環境変数を設定することにより、Pythonが .pycまたは.pyoファイルを書き込むのを防ぐことができるようになりました。この設定はsys.dont_write_bytecode変数としてPythonプログラムで使用でき 、Pythonコードは値を変更してインタープリターの動作を変更できます。

アップデート2010-11-27:Python 3.2は、.pyc特別な__pycache__サブフォルダーを導入することにより、ファイルでソースフォルダーが乱雑になる問題に対処しています。「Python 3.2の新機能-PYCリポジトリディレクトリ」を参照してください。


1
少なくともPython 2.7を実行しているOS X 10.8では、環境変数は影響しません。
ソリン2012年

5
インタプリタを(C ++プログラムに)埋め込む場合は、「Py_DontWriteBytecodeFlag = 1;」を使用します。あなたのソースコードで。これは、pydebug.hで宣言されたグローバルintです。
JimB 2014年

1
環境変数は2.7ではうまく機能しますが、他のユーザーがどのような問題を抱えているかはわかりません。ありがとう!
トーマス

8
OSX(10.8&10.10)でも私のために働きました。@sorin変数を適切にエクスポートしましたか? export PYTHONDONTWRITEBYTECODE=1
nevelis 2014年

1
あなたはpytestで同じことをする方法を知っていますか?

110
import sys

sys.dont_write_bytecode = True

25
私はこれを試してみましたが、インポートされたモジュールで機能します。具体的には、この変数が設定されると、後でインポートされたものはpycファイルを生成しません。嬉しいです。ありがとう。

これを親モジュールに追加するのではなく、参照されているスクリプトに追加してみてください。これはクールに動作します。ウィルソン@teのおかげ
Sathy

4
これをに追加して、site-packages/usercustomize.pyこれをすべてのスクリプトに適用します。私にとって、このディレクトリはでした$HOME/.local/lib/python2.6/site-pacakges/usercustomize.py。Cf. docs.python.org/2/tutorial/…– RobM、2014
1

3
私のサイトパッケージは/usr/local/lib/python2.7/site-packagesにあり、usercustomize.pyを作成する必要がありました
anon58192932

3
または、1行で:import sys; sys.dont_write_bytecode = True
ET-CS、

23

実際にはPython 2.3以降でそれを行う方法がありますが、少し難解です。これを理解しているかどうかはわかりませんが、次のことができます。

$ unzip -l /tmp/example.zip
 Archive:  /tmp/example.zip
   Length     Date   Time    Name
 --------    ----   ----    ----
     8467  11-26-02 22:30   jwzthreading.py
 --------                   -------
     8467                   1 file
$ ./python
Python 2.3 (#1, Aug 1 2003, 19:54:32) 
>>> import sys
>>> sys.path.insert(0, '/tmp/example.zip')  # Add .zip file to front of path
>>> import jwzthreading
>>> jwzthreading.__file__
'/tmp/example.zip/jwzthreading.py'

zipimportライブラリによると:

任意のファイルがZIPアーカイブに存在する可能性がありますが、ファイル.pyおよび.py [co]のみをインポートできます。動的モジュール(.pyd、.so)のZIPインポートは許可されていません。アーカイブに.pyファイルのみが含まれている場合、Pythonは対応する.pycまたは.pyoファイルを追加してアーカイブを変更しようとしないことに注意してください。つまり、ZIPアーカイブに.pycファイルが含まれていない場合、インポートはかなり遅くなる可能性があります。

したがって、ファイルをzip圧縮し、zipファイルをsys.pathに追加してインポートするだけです。

これをUNIX用に構築している場合は、次のレシピを使用してスクリプトをパッケージ化することも検討してください 。unixzip 実行可能ファイルですが、stdinを使用するか、sys.argsから何かを読み取る場合は、これを微調整する必要がある場合があります(それはあまり問題なく行われた)。

私の経験では、これが原因でパフォーマンスに大きな影響はありませんが、非常に大きなモジュールをこの方法でインポートする前に、よく考える必要があります。


11

2.5では、ユーザーにディレクトリへの書き込みアクセス権を与えないなどの対策を除いて、それを抑制する方法はありません。

ただし、python 2.6および3.0では、sysモジュールに「dont_write_bytecode」と呼ばれる設定があり、これを抑制するように設定できます。これは、「-B」オプションを渡すか、環境変数「PYTHONDONTWRITEBYTECODE」を設定することによっても設定できます。


7

sys.dont_write_bytecode = Trueソースで設定できますが、それは最初にロードされたpythonファイルにある必要があります。実行python somefile.pyすると、取得されませんsomefile.pyc

を使用setup.pyしてユーティリティをインストールすると、起動スクリプトentry_points=が設定さsys.dont_write_bytecodeれます。したがって、setuptoolsによって生成される「デフォルト」の起動スクリプトに依存することはできません。

自分でpythonファイルを引数としてPythonを起動する場合は、次のように指定できます-B

python -B somefile.py

somefile.pycとにかく生成されませんが.pyc、他のファイルのファイルもインポートされません。

ユーティリティがmyutilあり、それを変更できない場合、-Bはpythonインタープリターに渡されません。環境変数を設定して開始するだけですPYTHONDONTWRITEBYTECODE

PYTHONDONTWRITEBYTECODE=x myutil

4

テストスイートにいくつかのテストケースがあり、次のようにMacターミナルでテストスイートを実行する前に:

python LoginSuite.py

この方法でコマンドを実行すると、ディレクトリに.pycファイルが入力されていました。私は以下の方法を試してみて、問題を解決しました:

python -B LoginSuite.py

この方法は、テストケースをテストスイートにインポートし、コマンドラインでスイートを実行する場合に機能します。


4

Python 3.8以降では、環境変数PYTHONPYCACHEPREFIXを使用してPythonのキャッシュディレクトリを定義できます。

Pythonのドキュメントから:

これが設定されている場合、Pythonは.pycファイルを、ソースツリー内のpycacheディレクトリではなく、このパスのミラーディレクトリツリーに書き込みます。これは、-X pycache_prefix = PATHオプションを指定するのと同じです。

./profileLinuxで次の行を追加すると、

export PYTHONPYCACHEPREFIX="$HOME/.cache/cpython/"

Pythonは__pycache__プロジェクトディレクトリに迷惑なディレクトリを作成せず、代わりにそれらをすべて下に置きます~/.cache/cpython/


2

Pythonインタープリターを実行しているユーザーに対して、モジュールが存在するディレクトリーを読み取り専用にすることができます。

よりエレガントなオプションはないと思います。PEP 304はこのための簡単なオプションを導入する試みであったように見えますが、それは放棄されたようです。

解決しようとしている他の問題がおそらくあると思いますが、.py [co]を無効にすることで回避できるように見えますが、代わりにこの元の問題を攻撃する方が良いでしょう。


2

ソリューションipython 6.2.1 using python 3.5.2(Ubuntu 16.04およびWindows 10でテスト済み):

Ipythonインタプリタで%env PYTHONDONTWRITEBYTECODE =1設定されてipythonいるか、での起動中に設定されているかどうかは考慮されません~/.ipython/profile-default/startup/00-startup.ipy。代わりに以下を使用して~.ipython/profile-default/startup/00-startup.py

import sys
sys.dont_write_bytecode=True

0

私の知る限り、Pythonは「インポート」したすべてのモジュールをコンパイルします。ただし、pythonは「python script.py」を使用して実行されたpythonスクリプトをコンパイルしません(ただし、スクリプトがインポートするモジュールはコンパイルします)。

本当の質問は、なぜPythonにモジュールをコンパイルさせたくないのですか?それらが邪魔になっている場合は、おそらくこれらをクリーンアップする方法を自動化できます。


古いバイトコード.pycファイルがあることがよくあります。どういうわけか、クラス/モジュールを変更すると、.pycファイルが更新されません。そのため、.pyファイルを変更した後にインポートすると、ファイルが引き続き使用され、.pycエラーが発生します
alpha_989
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.