21

コードをインポートするさまざまな方法のうち、他の方法と比較して使用するのが好ましい方法はありますか?このリンクhttp://effbot.org/zone/import-confusion.htmは、簡単に言うと次のように述べています。

from foo.bar import MyClass

通常の状況で、または何をしているのかわからない場合を除いて、MyClassをインポートするための推奨される方法ではありません。(むしろ、より良い方法は次のようになります:

import foo.bar as foobaralias

次に、コードでMyClassにアクセスするには

foobaralias.MyClass

)。

要するに、上記のリンクは、モジュールの一部だけでなく、モジュールからすべてをインポートする方が通常は良いと言っているようです。

しかし、私がリンクしたその記事は本当に古いものです。

また、少なくともDjangoプロジェクトのコンテキストでは、モジュール全体ではなく、使用するクラスのみをインポートする方がよいと聞きました。このフォームは、循環インポートエラーを回避するのに役立つか、少なくともdjangoインポートシステムの脆弱性を軽減すると言われています。Django自身のコードは、「importx」よりも「fromximporty」を好むようであることが指摘されました。

私が取り組んでいるプロジェクトが__init__.py...の特別な機能を使用していないと仮定すると(すべての__init__.pyファイルが空です)、どのインポート方法を優先する必要がありますか、またその理由は何ですか?

4

3 に答える 3

13

まず、主要なインポートのルール:決して使用しないでfrom foo import *ください。

この記事では、循環インポートの問題について説明しています。これは、今日でも構造化されていないコードに存在します。私は周期的な輸入が嫌いです。それらの存在は、一部のモジュールが実行しすぎていることを示す強力な兆候であり、分割する必要があります。何らかの理由で、再配置できない循環インポートを使用するコードを操作する必要がある場合import fooは、それが唯一のオプションです。

ほとんどの場合、との間に大きな違いはありませimport foofrom foo import MyClass。タイピングが少ないので、2番目の方が好きですが、最初の方法を使用する理由はいくつかあります。

  • モジュールとクラス/値の名前は異なります。インポートされた値の名前がモジュールと無関係である場合、特定のインポートがどこから来ているのかを読者が思い出すのは難しい場合があります。

    • 良い:import myapp.utils as utils; utils.frobnicate()
    • 良い:import myapp.utils as U; U.frobnicate()
    • 悪い:from myapp.utils import frobnicate
  • 1つのモジュールから多くの値をインポートしています。あなたの指と読者の目を救ってください。

    • 悪い:from myapp.utils import frobnicate, foo, bar, baz, MyClass, SomeOtherClass, # yada yada
于 2009-11-09T21:56:50.417 に答える
6

私にとって、それは状況に依存します。それが一意の名前のメソッド/クラス(つまり、そうでないprocess()か、そのようなもの)であり、それを頻繁に使用する場合は、入力を保存して実行しますfrom foo import MyClass

1つのモジュールから複数のものをインポートする場合は、モジュールをインポートするだけでmodule.bar, module.foo, module.baz、名前空間をクリーンに保つなどの方法を実行することをお勧めします。

あなたも言った

このフォームは、循環インポートエラーを回避するのに役立つか、少なくともdjangoインポートシステムの脆弱性を軽減すると言われています。Django自身のコードは、「importx」よりも「fromximporty」を好むようであることが指摘されました。

いずれかの方法で循環輸入を防ぐのにどのように役立つかわかりません。その理由は、あなたがそうしてもfrom x import y、すべてxがインポートされるからです。現在の名前空間にのみy取り込まれますが、モジュール全体xが処理されます。この例を試してください:

test.pyに、次のように入力します。

def a():
    print "a"

print "hi"

def b():
    print "b"

print "bye"

次に、「runme.py」に次のように入力します。

from test import b

b()

次に、python runme.py

次の出力が表示されます。

hi
bye
b

したがって、インポートしただけでも、test.pyのすべてが実行されましたb

于 2009-11-09T22:10:43.773 に答える
2

後者の利点は、MyClassの起源がより明確になることです。前者はMyClassを現在の名前空間に配置するため、コードはMyClassを非修飾で使用できます。したがって、MyClassが定義されているコードを読んでいる人にはわかりにくいです。

于 2009-11-09T21:49:24.513 に答える