web-dev-qa-db-ja.com

Python-ベストプラクティスでモジュールをインポートする

Rを使用して学んだスキルを拡張したいので、私はPythonが初めてです。Rでは、多くのライブラリをロードする傾向があります。

Pythonのベストプラクティスは何ですか。特定のバリエーションを見たことがありますが、違いはありません

import pandasfrom pandas import *、およびfrom pandas import DataFrame

最初の2つの違いは何ですか。必要なものだけをインポートする必要があります。また、小さなプログラムを作成してデータを処理し、単純な統計を計算する人にとって最悪の結果は何でしょうか。

[〜#〜] update [〜#〜]

私はこれを見つけました 優秀なガイド 。それはすべてを説明します。

57
John

import pandasはpandas名前空間の下にpandasモジュールをインポートするため、pandas.fooを使用してpandas内のオブジェクトを呼び出す必要があります。

from pandas import *は、すべてのオブジェクトをpandasモジュールから現在のネームスペースにインポートするため、pandas内のオブジェクトをfooのみを使用して呼び出します。現在のネームスペースとpandasネームスペースの間に名前の競合がある場合、これにより実行できない結果が生じる可能性があることに注意してください。

from pandas import DataFrameは上記と同じですが、(すべてではなく)DataFrameのみを現在のネームスペースにインポートします。

私の意見では、最初の方法は一般的にベストプラクティスであり、さまざまなモジュールをコード内で適切に区分けします。

43
Paul

各フォームの欠点

他の人のコード(およびそれらの人が非常に異なるインポートスタイルを使用している)を読むと、各スタイルに次の問題があることに気付きました。

import modulewithaverylongnameは、長いモジュール名(たとえば、concurrent.futuresまたはDjango.contrib.auth.backends)これらの場所の読みやすさを低下させます。

from module import *は、たとえばclassAclassBが同じモジュールから来ており、互いに関係があることを構文的に見る機会を与えません。 。コードの読み取りを困難にしますhard。 (そのようなインポートからの名前は、以前のインポートからの名前を隠す可能性がありますが、それはその問題の最小の部分です。)

from module import classA, classB, functionC, constantD, functionEは、コードを一貫して理解するためにmoduleに精神的に割り当てる必要がある名前が多すぎるため、短期記憶を過負荷にします。

import modulewithaverylongname as mwvlnは、meのニーモニックが不十分な場合があります。

適切な妥協

上記の観察に基づいて、自分のコードで次のスタイルを開発しました。

import moduleは、たとえば標準ライブラリのほとんどのパッケージのようにモジュール名が短い場合に推奨されるスタイルです。また、自分のモジュール内の2〜3か所でのみモジュールの名前を使用する必要がある場合にも、推奨されるスタイルです。明快さは簡潔さよりも優先されます( "Readability counts" )。

import longername as lnは、他のほとんどすべての場合に推奨されるスタイルです。たとえば、import Django.contrib.auth.backends as dj_abe。上記の基準1の定義により、略語は頻繁に使用されるため、十分に覚えやすくなります。

"明示的は暗黙的よりも優れています。" ルールに従って、これら2つのスタイルのみが完全にPythonicです。

from module import xxは、私のコードでも時々発生します。 as形式でさえ誇張されている場合に使用します。最も有名な例はfrom datetime import datetime

29
Lutz Prechelt

一般に、明示的なインポートを行う方が適切です。次のように:

import pandas
frame = pandas.DataFrame()

または:

from pandas import DataFrame
frame = DataFrame()

競合する名前がある場合のPythonの別のオプションは、xをyとしてインポートすることです。

from pandas import DataFrame as PDataFrame
from bears import DataFrame as BDataFrame
frame1 = PDataFrame()
frame2 = BDataFrame()
23

PEP8スタイルガイドの推奨事項を次に示します。

  1. インポートは通常、別々の行にある必要があります、例えば:

    Yes: import os
         import sys
    
    No:  import sys, os
    

    でも大丈夫です

    from subprocess import Popen, PIPE
    
  2. インポートは常にファイルの先頭、モジュールのコメントとドキュメント文字列の直後、モジュールのグローバルと定数の前に置かれます。

    • インポートは、次の順序でグループ化する必要があります。
      1. 標準ライブラリのインポート
      2. 関連する第三者の輸入
      3. ローカルアプリケーション/ライブラリ固有のインポート
    • インポートの各グループの間に空白行を挿入する必要があります。
  3. 絶対的なインポートが推奨されます
    これらは読みやすく、インポートシステムを台無しにした場合に備えてより良いエラーメッセージを表示することでデバッグを容易にします。

    import mypkg.sibling
    from mypkg import sibling
    from mypkg.sibling import example
    

    またはexplicit relative imports

    from . import sibling
    from .sibling import example
    
  4. 暗黙の相対インポートは決して使用されるべきではなく、Python 3。

    No:  from ..grand_parent_package import uncle_package
    
  5. ワイルドカードのインポート(from <module> import *)は避けるべきですツール。


python速度パフォーマンスのヒントからのlazy importsに関するいくつかの推奨事項。

インポートステートメントのオーバーヘッド

importステートメントは、ほぼどこでも実行できます。可視性を制限したり、初期起動時間を短縮したりするために、関数内に配置すると便利な場合があります。 Pythonのインタープリターは同じモジュールを複数回インポートしないように最適化されていますが、importステートメントを繰り返し実行すると、状況によってはパフォーマンスに重大な影響を与える可能性があります。

以下に示すのは、ページで説明されているシナリオです。

>>> def doit1():
... import string
... string.lower('Python')
...
>>> import string
>>> def doit2():
... string.lower('Python')
...
>>> import timeit
>>> t = timeit.Timer(setup='from __main__ import doit1', stmt='doit1()')
>>> t.timeit()
11.479144930839539
>>> t = timeit.Timer(setup='from __main__ import doit2', stmt='doit2()')
>>> t.timeit()
4.6661689281463623
14
from A import B

本質的に次の3つのステートメントに等しい

import A
B = A.B
del A

それだけです、それだけです。

9
XuZhangning

それらはすべて異なるコンテキストに適しています(だからこそ、すべて利用可能です)。明快さ、保守性、シンプルさに関する一般的な母親の声明以外に、深い指導原則はありません。私自身のコードからのいくつかの例:

  1. _import sys, os, re, itertools_は名前の衝突を回避し、多数の標準モジュールをインポートする非常に簡潔な方法を提供します。
  2. _from math import *_を使用すると、数学が重いコードでsin(x)の代わりにmath.sin(x)を記述できます。私はnumpyをインポートするときに少し危険を感じますが、これはこれらのいくつかを倍にしますが、とにかく同じ機能であるため、あまり心配しません。また、numpyのドキュメント(_import numpy as np_)に従う傾向があります。これは、問題を完全に回避します。
  3. _from PIL import Image, ImageDraw_を好むのは、それがPILドキュメントがその例を提示する方法だからです。
2
Marcelo Cantos