19

モジュールを含むパッケージがあるとします。

SWS/
  __init.py__
  foo.py
  bar.py
  time.py

モジュールは、互いに含まれる関数を参照する必要があります。time.py同じ名前の標準モジュールがあるため、モジュールで問題が発生したようです。

たとえば、私のモジュールが私のモジュールと標準の Pythonモジュールのfoo.py両方を必要とする場合、インタープリターがパッケージ内を調べて、標準モジュールに遭遇する前に 私のモジュールを見つけてしまうため、問題が発生します。SWS.timetimetime.pytime

これを回避する方法はありますか?これはノーノーの状況であり、モジュール名を再利用すべきではありませんか?

パッケージの哲学に関する解決策や意見は、ここで役立ちます。

4

4 に答える 4

18

標準の関数/クラス/モジュール/パッケージの名前を再利用することは決して良い考えではありません。できるだけ避けるようにしてください。ただし、状況に対する明確な回避策があります。

SWS.timestdlib の代わりにyour をインポートするという動作は、古い python バージョン (2.x)timeのセマンティクスによるものです。importそれを修正するには、次を追加します。

from __future__ import absolute_import

ファイルの一番上にあります。これにより、 のセマンティクスがimportより賢明な python3.x のセマンティクスに変更されます。その場合、ステートメント:

import time

トップレベルのモジュールのみを参照します。そのため、インタープリターはパッケージ内でそのインポートを実行するときにモジュールを考慮しませんSWS.timeが、標準ライブラリのみを使用します。

パッケージのモジュールをインポートする必要SWS.timeがある場合は、次の選択肢があります。

  • 明示的な相対インポートを使用する:

    from . import time
    
  • 絶対インポートの使用:

    import SWS.time as time
    

したがって、あなたfoo.pyは次のようになります。

from __future__ import absolute_import

import time

from . import time as SWS_time
于 2015-03-04T12:14:05.597 に答える
10

使用している Python のバージョンによって異なります。対象となる Python のバージョンが 2.4 以前 (2015 年にはそうでないことを願っています) の場合、2 つのモジュールを区別する方法 (ハックなし) がないため、それは悪い習慣です。

ただし、Python 2.5 以降では、パッケージの名前空間内で標準の lib モジュール名を再利用することはまったく問題ないと思います。実際、それがPEP328 の精神です

Python のライブラリが拡大するにつれて、ますます多くの既存のパッケージ内部モジュールが、突如として標準ライブラリ モジュールの影になります。どのモジュールが意図されているかを特定する方法がないため、パッケージ内では特に難しい問題です。あいまいさを解決するために、 foo は常に sys.path から到達可能なモジュールまたはパッケージにすることが提案されています。これを絶対インポートと呼びます。

python-dev コミュニティは、絶対インポートがより一般的なユース ケースであり、絶対インポートが相対 (パッケージ内) インポートのすべての機能を提供できるため、デフォルトとして絶対インポートを選択しました。階層内で、またはあるパッケージを別のパッケージ内に移動する場合。

これはセマンティクスの変更を表すため、絶対インポートは Python 2.5 および 2.6 ではオプションになります。from __future__ import absolute_import

SWS.timeは明らかにコードのリーダーと同じではありません。私はを使用するだけでなく、何らかの方法でコードを拡張することtimeを期待しています。SWS.timetime

したがって、SWS.fooインポートする必要がある場合SWS.timeは、絶対パスを使用する必要があります。

# in SWS.foo

# I would suggest renaming *within*
# modules that use SWS.time so that
# readers of your code aren't confused
# with which time module you're using
from SWS import time as sws_time

または、Bakuriu の回答のように、明示的な相対インポートを使用する必要があります。

# in SWS.foo

from . import time as sws_time

timeモジュール内に標準の lib モジュールをインポートする必要がある場合SWS.timeは、最初に将来の機能をインポートする必要があります (Python 2.5+ のみ; Python 3+ はデフォルトでこれを行います):

# inside of SWS.time
from __future__ import absolute_import

import time

time.sleep(28800)  # time for bed

注: は、将来の機能がインポートされるモジュールfrom __future__ import absolute_importsのimport ステートメントにのみ影響し、他のモジュールには影響しません(別のモジュールが相対インポートに依存している場合は有害であるため)。

于 2015-11-01T15:54:23.250 に答える
5

他の人が言ったように、これは一般的に悪い考えです。

そうは言っても、潜在的な回避策を探している場合、または問題をよりよく理解している場合は、次の SO の質問を読むことをお勧めします。

于 2012-05-08T15:24:49.893 に答える
0

ええ、本当にそれを回避する良い方法はありません。モジュールに標準パッケージのような名前を付けないようにしてください。module を本当に呼び出したい場合は、代わりにtime使用することをお勧めし_time.pyます。たとえそれを行う方法があったとしても、2 つの時間モジュールになると、コードが読みにくくなり、混乱することになります。

于 2012-05-08T15:19:55.810 に答える