Pythonでのimportの使い方【はっきり書いてあります!】


この文章ははっきり書いてあります.https://zhuanlan.zhihu.com/p/63143493、権利侵害があれば連絡してください.すぐに削除します.
Pythonは2年近く使っているでしょう.中にはずっとぼんやり使っているものもあります.importは私がずっと理解していないものです.かつて3回もその解決の機会があったが、私はすべて過ちを犯し、引きずって敵を友にすることができなかった.今日の午后、それはまた私にチャンスを与えて、私はやはりその愿いからだと思います.
物語はこの台湾同胞のブログ(PythonのImportトラップ)から始まり、PythonコミュニティのPEP 328提案(PEP 328--Imports:Multi-Line and Absolute/Relative)に飛び込んで、過去の経験といくつかのテストを結びつけて、多分わかったと思います.以下は私の総括で、内容が簡潔で、理解しやすいことを望んでいます.
import文は何の役に立ちますか?import文は、モジュールmoduleと呼ばれる他のpythonファイルをインポートするために使用され、このモジュールで定義されたクラス、メソッド、または変数を使用して、コード多重化の目的を達成します.説明を簡単にするために、importの使い方を例で説明すると、読者の皆さんは試してみることができます(python 3、python 2、python 3はimportの表現に違いがあり、後で言及します).
まず、作業ディレクトリとしてフォルダTreeを作成する、その内に2つのファイルm 1を作成する.pyとm 2.py,m 1.py書き込みコード:
import os
import m2
m2.printSelf()

m 2.py書き込みコード:
def printSelf():
	print('In m2')

コマンドラインを開き、Treeディレクトリの下に入り、python m1.pyをノックして実行し、エラーが報告されていないことを発見し、In m2を印刷し、importを使用して問題がないことを示します.これによりimport文の最初の使い方をまとめた.
  • import module_name .すなわちimport後にモジュール名を直接接続します.この場合、Pythonは2つの場所でこのモジュールを探します.1つ目はsysです.path(実行コードimport sys; print(sys.path)で表示)、osというモジュールが存在するディレクトリはリストsysにある.pathでは、一般的にインストールされているPythonライブラリのディレクトリはsys.Pathで見つけた(Pythonのインストールディレクトリをパソコンの環境変数に追加することを前提としている)ので、インストールしたライブラリについては直接importでいいです.2つ目は、m 2のため、実行ファイル(ここではm 1.py)が存在するディレクトリです.pyと実行ファイルは同じディレクトリの下にあるので、上記の書き方は問題ありません.

  • 上記の方法で従来のsysを導入する.pathのライブラリに問題はありません.ただし、上記の方法で同じディレクトリの下のファイルをインポートしないほうがいいです!これは間違いかもしれないからです.このエラーをプレゼンテーションするにはimport文の2番目の書き方が必要ですので、まずimportの2番目の書き方を学びましょう.Treeディレクトリの下に新しいディレクトリBranchを作成し、Branchにファイルm 3を作成します.py,m3.pyの内容は次のとおりです.
    def printSelf():
    	print('In m3')

    m 1にm 3をインポートする方法pyは、変更後のm 1を見てください.py:
    from Branch import m3
    m3.printSelf()

    import文の2つ目の使い方をまとめます.
  • from package_name import module_name .一般にモジュールからなる集合をパッケージ(package)と呼ぶ.最初の書き方と同じように、Pythonはsysにあります.pathと実行ファイルディレクトリの2つの場所でパッケージを探し、module_というパッケージをインポートします.nameのモジュール.

  • 次に、importの最初の書き方で同じディレクトリの下のファイルをインポートしない理由について説明します.Branchディレクトリの下にm 4を新規作成する.pyファイル、m 4.pyの内容は次のとおりです.
    def printSelf():
    	print('In m4')

    そして私たちはm 3にいます.pyにm 4,m 3を直接インポートする.pyが次のようになります.
    import m4
    def printSelf():
    	print('In m3')

    このときm 1を実行する.pyはm 4モジュールをインポートできないとエラーを報告します.どうしてですか.インポートプロセスを見てみましょう.m 1はfrom Branch import m3を使用してm 3をインポートし、m 3にインポートします.pyではm 4をimport m4でインポートします.問題は見えましたか.m4.pyとm 1.pyが同じディレクトリにないのに、import m4を直接使用してm 4をインポートすることはできません.(Treeディレクトリの下に別のm 4.pyファイルを直接作成してみると、m 1.pyを再実行してもエラーはありませんが、2番目のm 4.pyをインポートしています)
    上記のエラーに対してpython 2を使用してm 1を実行します.pyは、python 2では、上述したimportの2つの書き方が相対インポートに属し、python 3では絶対インポートに属するため、エラーは発生しません.ここまで言うと、importの最も重要な部分である相対導入と絶対導入にかかわる.
    python 3のimportの使い方について話します.上記の2つの書き方は、sysをインポートするための絶対インポートに属する.pathのパッケージと実行ファイルがあるディレクトリの下のパッケージ.sysについてpathの中のバッグ、この書き方は問題ありません;自分で書いたファイルをインポートします.非実行エントリファイル(上のm 1.pyが実行エントリファイルで、絶対インポートを使用できます)の場合は、相対的にインポートする必要があります.
    例えば、非実行エントリファイルm 3について.py、m 4をインポートする.pyは、相対インポートを使用する必要があります.
    from . import m4
    def printSelf():
    	print('In m3')

    このときm 1を運転する.pyでOKです.相対的に導入された書き方を列挙します.
  • from . import module_name .自分と同じディレクトリのモジュールをインポートします.
  • from .package_name import module_name .自分と同じディレクトリのパッケージをインポートするモジュール.
  • from .. import module_name .親ディレクトリのモジュールをインポートします.
  • from ..package_name import module_name .親ディレクトリの下にあるパッケージのモジュールをインポートします.
  • はもちろん、より多くの.を持っていて、1つ以上のポイントごとに1階のディレクトリに追加することができます.

  • 「上のm 1.pyはエントリファイルを実行しているので、絶対インポートを使うことができます」という言葉に気をつけているかどうか分かりませんが、この言葉は大丈夫で、私の普段のやり方と一致しています.では、実行入口ファイルは相対インポートを使用できますか?例えばm 1.py内容変更:
    from .Branch import m3
    m3.printSelf()

    答えは可能ですが、python m1.pyコマンドではなく、Treeがあるディレクトリに入り、python -m Tree.m1を使用して実行する必要があります.どうして?前者については、PEP 328の提案の一節が原因を示しているようです.
    Relative imports use a module's _name
    _ attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to '__main
    __') then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.
    よくわかりませんが、少し分かります.次のコードを見たことがあります.
    if __name__ == '__main__':
    	main()

    現在のファイルが実行されている場合、name__変数は__に設定されます.main__,次にmain関数が実行され、現在のファイルが他のファイルにモジュールとしてインポートされている場合は_name__モジュール名、等しくない_main__,main関数は実行されません.例えば、上記変更後のm 1について.py、python m1.pyコマンドを実行すると、次のエラーが表示されます.
    Traceback (most recent call last): File "m1.py", line 1, in from .Branch import m3 ModuleNotFoundError: No module named '_
    main_.Branch'; '__main__' is not a package
    これにより、python m1.pyコマンドを実行すると、現在のディレクトリが表すパッケージ'.'になりましたmain__.
    では、なぜpython -m Tree.m1でいいのでしょうか.その台湾の先生は説明した.
    実行命令の-mは、Pythonが必要なpackageまたはmoduleを事前にimportしてからscriptを実行するためです.
    すなわちm 1をpyは実行エントリファイルとしてではなく、インポートされたモジュールとしても扱われており、非実行エントリファイルと同様に表現されています.
    Treeディレクトリでpython -m m1を実行することはできません.ImportError:attempted relative import with no known parent packageのエラーが表示されます.なぜならm 1.pyのfrom .Branch import m3.で、解釈器はどのpackageなのか分かりません.python -m Tree.m1を使用すると、解釈器は.がTreeというパッケージに対応していることを知っています.
    逆にm 1ならpyはアブソインポート(from Branch import m3)を使用して、python -m m1で実行できますか?試してみましたが、現在のディレクトリがTreeであればいいです.Treeが存在するディレクトリ(python -m Tree.m1を使用して実行)のような他のディレクトリで実行する場合は、できません.これは、絶対インポートに関連する可能性があります.
    (以前は大きなプロジェクトを見ていましたが、その実行入口ファイルには相対的なインポートがたくさんあり、私はpythonで直接実行していました.その後、彼が与えたサンプル実行コマンドが-mパラメータを持っているのを見ました.今やっと悟りました.)
    importの難点を理解するのは悪くない.次にimportの他の簡単だが実用的な使い方を説明します.
  • import moudle_name as alias .一部module_nameは長いので、後で書くのが面倒かmodule_nameは名前の衝突が発生し、asでimport numpy as npのように名前を変更することができます.
  • from module_name import function_name, variable_name, class_name .上にインポートしたのはすべてモジュール全体で、モジュールの中のいくつかの関数、いくつかの変数、いくつかのクラスだけを使用したい場合があります.このような書き方でいいです.コンマを使用して、モジュール内の複数の要素をインポートします.
  • は、インポートされる要素が多く、反スラッシュで改行できる場合がありますが、カッコの使用を推奨します.
  • from Tkinter import Tk, Frame, Button, Entry, Canvas, Text, \
        LEFT, DISABLED, NORMAL, RIDGE, END	#      
    from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,
        LEFT, DISABLED, NORMAL, RIDGE, END)	#     (  )

    そういえばimportのコアはもう終わりました.上のブログについて、importを使うと問題になるかもしれません.
    問題1説明:ValueError:attempted relative import beyond top-level package.問題に直面する第一歩はそれを理解することであり、それを再現し、2つの間に横たわって私たちが蹂躙するようにしたほうがいい.依然として上の4つのファイルで、少し修正して、4つのファイルは以下の通りです.
    # m1.py
    from Branch import m3
    m3.printSelf()
    # m2.py
    def printSelf():
    	print('module2')
    # m3.py
    from .. import m2 #         #
    print(__name__)
    def printSelf():
    	print('In m3')
    # m4.py
    def printSelf():
    	print('In m4')
    python m1.pyを実行すると、この問題が発生します.問題は何ですか.m 1を実行すると推測します.py後、m 1が表すモジュールは最上位モジュール(PEP 328の参照)であり、m 3.pyでインポートしようとしたm 2モジュールが存在するパケット(すなわちTreeディレクトリが表すパケット)はm 1のレベルよりも高いため、このようなエラーが報告されます.どうやって解決しますか?m 1.pyのすべてのインポートを相対インポートに変更し、m 1に進みます.pyの上位ディレクトリは、python -m Tree.m1を実行すればよい.
    importを使用して発生した他の問題に対して、出会ってから更新します.