71

失敗した将来の機能のインポートをどのように適切に処理しますか? ユーザーが Python 2.5 を使用して実行していて、モジュールの最初のステートメントが次の場合:

from __future__ import print_function

このモジュールを Python 2.5 用にコンパイルすると、次のエラーで失敗します。

  File "__init__.py", line 1
    from __future__ import print_function
SyntaxError: future feature print_function is not defined

Python >= 2.6 でプログラムを再実行する必要があることをユーザーに通知し、その方法についていくつかの指示を提供したいと思います。ただし、PEP 236を引用するには:

future_statement の前に表示できる行は次のとおりです。

  • モジュールのドキュメント文字列 (存在する場合)。
  • コメント。
  • 空行。
  • その他の future_statements。

だから私は次のようなことはできません:

import __future__

if hasattr(__future__, 'print_function'):
    from __future__ import print_function
else:
    raise ImportError('Python >= 2.6 is required')

それが得られるからです:

  File "__init__.py", line 4
    from __future__ import print_function
SyntaxError: from __future__ imports must occur at the beginning of the file

PEP からのこのスニペットは、インラインで行うことを期待しているようです:

Q: future_statements を try/except ブロックでラップしたいので、実行している Python のバージョンに応じて異なるコードを使用できます。なぜできないのですか?

A: すみません!try/except はランタイム機能です。future_statements は主にコンパイル時のギミックであり、try/except はコンパイラが完了してからずっと後に発生します。つまり、try/except を実行するまでに、モジュールに有効なセマンティクスは既に完了しています。トライ/エクセプトでは、達成すべきと思わ れることを達成できないため、単純に許可されていません。また、これらの特別なステートメントを簡単に見つけて認識できるようにしたいと考えています。

__future__ を直接インポートし、その中の情報を sys.version_info と一緒に使用して、実行中のリリースが特定の機能のステータスに関連してどこにあるのかを把握できることに注意してください。

アイデア?

4

3 に答える 3

60

「Python>=2.6でプログラムを再実行する必要があることをユーザーに通知し、その方法についていくつかの指示を提供したいと思います。」

それがREADMEファイルの目的ではありませんか?

これがあなたの選択肢です。「ラッパー」:ターゲットのアスペクト指向プログラミングを実行する前に環境をチェックするPythonの小さなブロブ。

ファイル:appwrapper.py

import sys
major, minor, micro, releaselevel, serial = sys.version_info
if (major,minor) <= (2,5):
    # provide advice on getting version 2.6 or higher.
    sys.exit(2)
import app
app.main()

「直接インポート」とはどういう意味ですか。の内容を調べることができます__future__。aはコンパイラへの情報であるという事実にまだ縛られてfrom __future__ import print_functionいますが、実際の作業を行うモジュールをインポートする前に、いろいろと調べてみることができます。

import __future__, sys
if hasattr(__future__, 'print_function'): 
    # Could also check sys.version_info >= __future__. print_function.optional
    import app
    app.main()
else:
    print "instructions for upgrading"
于 2008-12-23T03:20:03.067 に答える
47

私が以前に使用したかなりハックだが単純な方法は、バイト リテラルが Python 2.6 で導入されたという事実を利用し、ファイルの先頭近くで次のようなものを使用することです。

b'This module needs Python 2.6 or later. Please do xxx.'

これは Python 2.6 以降では無害ですが、SyntaxErrorそれ以前のバージョンでは問題ありません。ファイルをコンパイルしようとするとエラーが発生しますが、指定したいメッセージも表示されます。

from __future__ import print_functionこの行の後にこの行が必要なので、それを生成するのはインポートであり、有用なエラー メッセージは表示されないと思うかもしれませんがSyntaxError、不思議なことに後のエラーが優先されます。インポートからのエラー自体は実際には構文エラーではないため、最初のコンパイル パスでは発生しないため、実際の構文エラーが最初に発生すると思われます (推測ではありますが)。

これは「優雅」であるという基準を満たしていない可能性があり、非常に Python 2.6 固有ですが、すばやく簡単に実行できます。

于 2010-06-14T12:36:33.363 に答える
40

"from __future__ import ..."次のように、と同じ行にコメントを入れるだけです。

from __future__ import print_function, division  # We require Python 2.6 or later

Python はエラーを含む行を表示するため、Python 2.5 でモジュールを実行しようとすると、わかりやすいエラーが表示されます。

    from __future__ import print_function, division  # We require Python 2.6 or later
SyntaxError: future feature print_function is not defined
于 2011-08-31T05:10:18.390 に答える