Python 2.4のコンテキストクラスを扱う
-
29-09-2019 - |
質問
Python-Daemonモジュールを使用しようとしています。 Daemon.daemonContextクラスに供給され、スクリプトを適切にデーモニ化します。私は主にPython 2.6+をターゲットにしていますが、バージョン2.4への逆方向の互換性を維持したいと思います。
Python 2.5は、コンテキストのインポートをサポートしています 将来, 、しかし、Python 2.4にはそのような施設はありません。ステートメントを上げてエラーをキャッチし、2.4で手動でコンテキストを入力して終了することができると考えましたが、syntaxerrorをキャッチすることはできません。
通訳バージョンを明示的にチェックする以外にこれを達成する方法はありますか?以下は、私がやろうとしていることの要点と、私が得ている問題です。実生活では、私はコンテキストクラスをコントロールしていないので、元のクラスを操作することなく動作する必要があります。 これらのアイデア。
Python 2.4がPython-Daemonを実行できない場合は気にしないでください。少なくともエラーをキャッチし、フォールバックなどを実装することができます。
助けてくれてありがとう。
#!/usr/bin/python2.4
from __future__ import with_statement
# with_statement isn't in __future__ in 2.4.
# In interactive mode this raises a SyntaxError.
# During normal execution it doesn't, but I wouldn't be able to catch it
# anyways because __future__ imports must be at the beginning of the file, so
# that point is moot.
class contextable(object):
def __enter__(self):
print('Entering context.')
return None
def __exit__(self, exc_type, exc_val, exc_tb):
print('Exiting context.')
return False
def spam():
print('Within context.')
context = contextable()
try:
with context: # This raises an uncatchable SyntaxError.
spam()
except SyntaxError, e: # This is how I would like to work around it.
context.__enter__()
try:
spam()
finally:
context.__exit__(None, None, None)
解決
SyntaxError
コンパイル時にPythonコンパイラによって診断されます - おそらく、同じモジュールの一部としてコンパイルされているコードから「キャッチ」しようとしていると思われます(たとえば、コードサンプルでやっていることです)。うまくいきません - あなたの「キャッチ」コードはまだコンパイルされていません(コンピレーションが失敗したため)ので、何もキャッチできません。
構文エラーがコンパイルされる可能性のあるコードを確認する必要があります 後で キャッチングコードよりも - でインポートする別のモジュールに入れます try
句、または文字列であなた compile
その名前で組み込まれたものを使用して(後で結果として生じるバイトコードを実行できます compile
正常に終了した場合、電話)。
どちらの可能性もあなたの目的には良くないと思います。残念ながら、2つの別々のモジュールを使用して(おそらく「このコンパイル」チェックを行う」ことによっては、おそらくそれらを選択しますが、バージョンチェックは私にとってはるかにきれいに聞こえます)と思われます。
編集: :バージョンのチェックを除いて、マイクロバンチマークのtry/を除いて次の方法を次に示します。
$ python2.4 -mtimeit 'try:
compile("with x: pass", "", "exec")
except SyntaxError: x=1
else: x=2'
100000 loops, best of 3: 10.8 usec per loop
$ python2.6 -mtimeit 'try:
compile("with x: pass", "", "exec")
except SyntaxError: x=1
else: x=2'
10000 loops, best of 3: 40.5 usec per loop
$ python2.4 -mtimeit -s'import sys' 'if sys.version>="2.5": x=2
else: x=1'
1000000 loops, best of 3: 0.221 usec per loop
$ python2.6 -mtimeit -s'import sys' 'if sys.version>="2.5": x=2
else: x=1'
10000000 loops, best of 3: 0.156 usec per loop
ご覧のとおり、私がクリーナーと思うバージョンは 10.8 / 0.221
, 、2.4でほぼ50倍高速で、 40.5 / 0.156
, 、2.6でほぼ260倍高速です。一般的に(まれな例外を除いて)、クリーン(つまり、「Pythonic」)アプローチはPythonでより良い最適化されたアプローチであることが判明します。嫌いな構造物ではなく、好きな構造物の使用。