64

比較的長いモジュールがあり、外部モジュールまたはメソッドが必要なのは一度だけだとします。

モジュールの途中でそのメソッドまたはモジュールをインポートしても問題ありませんか?

またはimport、モジュールの最初の部分のみにある必要があります。

例:

import string, pythis, pythat
...
...
...
...
def func():
     blah
     blah 
     blah
     from pysomething import foo
     foo()
     etc
     etc 
     etc
...
...
...

回答の正当性を示し、 PEPまたは関連ソースへのリンクを追加してください

4

9 に答える 9

65

PEP 8は、次のように正式に述べています。

インポートは、モジュールのコメントとdocstringの直後、モジュールのグローバル変数と定数の前に、常にファイルの先頭に配置されます。

PEP 8は、コアPythonチームが全体として最も効果的なスタイルであると判断したものを要約しているため、「社内」スタイルガイドの基礎となるはずです(もちろん、他の言語と同様に、個人の反対意見もありますが、コンセンサスがあります)。 BDFLはPEPに同意します8)。

于 2009-07-27T14:59:05.237 に答える
28

このトピックについては、2001 年に Python メーリング リストで詳細な議論が行われました。

https://mail.python.org/pipermail/python-list/2001-July/071567.html

そのスレッドで議論されている理由のいくつかを次に示します。Peter Hansen によると、インポートをすべてファイルの先頭に配置しない理由が 3 つあります。

関数にインポートする考えられる理由:

  1. 読みやすさ: インポートが 1 つの関数でのみ必要であり、それが変更される可能性がほとんどない場合は、そこにのみ配置する方が明確でクリーンな場合があります。

  2. 起動時間: 関数定義の外にインポートがない場合、モジュールが別のモジュールによって最初にインポートされたときに実行されず、関数の 1 つが呼び出されたときにのみ実行されます。これにより、インポートのオーバーヘッドが遅延します (または、関数が呼び出されない可能性がある場合は回避されます)。

  3. 私たちがこれまで考えてきた理由よりも、常にもう1つの理由があります。

ヴァン・ロッサムは 4 番目の音を出しました。

  1. オーバーヘッド: モジュールが多数のモジュールをインポートする場合、実際に使用されるモジュールはごくわずかです。これは「起動時間」の理由と似ていますが、もう少し先です。モジュールを使用するスクリプトが機能の小さなサブセットのみを使用する場合、特に回避できるインポートが多くのモジュールもインポートする場合、かなりの時間を節約できます。

ローカル インポートは循環インポートの問題を回避する方法であるため、5 番目のオプションが提供されました。

完全な議論については、そのスレッドを自由に読んでください。

于 2009-07-27T15:02:08.773 に答える
20

他の誰もがすでに PEP について言及していますが、重要なコードの途中に import ステートメントがないように注意してください。少なくとも Python 2.6 では、関数に import ステートメントがある場合、さらにいくつかのバイトコード命令が必要です。

>>> def f():
    from time import time
    print time()

>>> dis.dis(f)
  2           0 LOAD_CONST               1 (-1)
              3 LOAD_CONST               2 (('time',))
              6 IMPORT_NAME              0 (time)
              9 IMPORT_FROM              0 (time)
             12 STORE_FAST               0 (time)
             15 POP_TOP             

  3          16 LOAD_FAST                0 (time)
             19 CALL_FUNCTION            0
             22 PRINT_ITEM          
             23 PRINT_NEWLINE       
             24 LOAD_CONST               0 (None)
             27 RETURN_VALUE

>>> def g():
    print time()

>>> dis.dis(g)
  2           0 LOAD_GLOBAL              0 (time)
              3 CALL_FUNCTION            0
              6 PRINT_ITEM          
              7 PRINT_NEWLINE       
              8 LOAD_CONST               0 (None)
             11 RETURN_VALUE  
于 2009-07-27T16:27:29.433 に答える
12

インポートされたモジュールの使用頻度が低く、インポートにコストがかかる場合は、中間インポートで問題ありません。

それ以外の場合は、AlexMartelliの提案に従うのが賢明です。

于 2009-07-27T14:59:13.913 に答える
8

これは一般的に悪い習慣と考えられていますが、避けられない場合もあります(たとえば、循環インポートを回避する必要がある場合)。

必要な場合の例:Wafを使用してすべてのコードをビルドします。システムはツールに分割され、各ツールは独自のモジュールに実装されます。各ツールモジュールは、detect()前提条件が存在するかどうかを検出する方法を提供できます。これらの1つの例は、次のことを行う場合があります。

def detect(self):
    import foobar

これが正しく機能する場合、ツールは使用可能です。その後、同じモジュールでfoobarモジュールが必要になる可能性があるため、関数レベルのスコープで再度インポートする必要があります。明らかに、モジュールレベルでインポートされた場合、物事は完全に爆発します。

于 2009-07-27T14:57:40.233 に答える
7

ファイルの先頭ですべてのインポートをグループ化することは「適切な形式」と見なされます。

モジュールは他のモジュールをインポートできます。慣例ですが、すべてのインポートステートメントをモジュール(またはスクリプト)の先頭に配置する必要はありません。インポートされたモジュール名は、インポートするモジュールのグローバルシンボルテーブルに配置されます。

ここから: http: //docs.python.org/tutorial/modules.html

于 2009-07-27T14:57:15.973 に答える
3

PEP8

インポートは、モジュールのコメントとdocstringの直後、モジュールのグローバル変数と定数の前に、常にファイルの先頭に配置されます。

輸入品をすくい取ったのは悪い習慣ではありません。インポートがで使用した関数にのみ適用されるようにします。

インポートがブロックの上部にグループ化されている場合、またはファイルの上部にグローバルに配置する場合は、コードが読みやすくなると思います。

于 2009-07-27T14:59:36.003 に答える
2

さて、どのライブラリがロードされているか知りたい場合はどこを見ればよいか誰もが知っているので、ファイルの先頭ですべてのインポートをグループ化することは良い習慣だと思います

于 2009-07-27T15:00:08.247 に答える