ホームページ  >  記事  >  バックエンド開発  >  Python モジュールのインポート メカニズムと大規模プロジェクトの仕様を学びます

Python モジュールのインポート メカニズムと大規模プロジェクトの仕様を学びます

coldplay.xixi
coldplay.xixi転載
2020-09-27 17:38:162807ブラウズ

Python ビデオ チュートリアル 今日のコラムでは、Python モジュールのインポート メカニズムと大規模プロジェクトの仕様について学習する方法を紹介します。

Python モジュールのインポート メカニズムと大規模プロジェクトの仕様を学びます

まえがき

日々のプロジェクトで Python を使用するプロセスでは、各モジュールのインポートの問題を解決する必要があり、リファレンスに遭遇することがよくあります。モジュールの相互インポートなどの問題があるため、Python のモジュールインポートの仕組みと、日常の大規模プロジェクトで従うべきモジュールインポートの仕様について説明するためにこの記事を書きました

Python モジュールimport

日々のプログラミングでは、作成したコードロジックを再利用するためにモジュールにカプセル化し、必要に応じて直接インポートして再利用することで開発効率を向上させます。 モジュールは関数、クラス、変数を定義でき、実行可能コードを含めることもできます。モジュール ソースには次の 3 種類があります。 ①Python組み込みモジュール(標準ライブラリ) ②サードパーティ製モジュール。 ③ カスタム モジュール;

インポートの原則

モジュールのインポートは、通常、ファイル ヘッダーの import キーワードを使用して行われます。モジュールのインポートは、モジュールを 1 回実行することと同等です。 module をインポートし、この名前空間にインポートされたモジュールの名前空間との接続を確立します。これは、この名前空間に新しい変数を作成するのと同じです。この変数の名前は、インポートされたモジュールの名前であり、インポートされたモジュールの名前空間。したがって、インポートされたモジュールは変数と同等です。 したがって、同じモジュールを複数回インポートしても、最初にインポートされたときにのみ実行されます。 (後続のインポートでは、モジュール変数がすでに存在していると判断され、実行されません)

Python モジュールのインポート メカニズムと大規模プロジェクトの仕様を学びます

パス検索メカニズム

インポートされたすべてのモジュールは、Python 組み込み辞書 sys.modules に格納されます。 Python が開始され、メモリにロードされ、新しいモジュールをインポートすると、sys.modules が自動的にモジュールを記録します。 Python のモジュール検索パス メカニズムは次のとおりです:

  1. モジュールが sys.path 内のすべてのパスに存在するかどうかを確認し、存在する場合は、モジュールをロードするための新しいスペースを開きます。
  2. sys.modules に組み込みパッケージまたはインストールされたサードパーティ パッケージがあるかどうかを確認し、存在する場合は、モジュールをロードするための新しいスペースを開きます。 PyPi に関しては、pip install で直接インストールし、起動時にメモリにロードできます。sys.modules を通じて表示できます。 このプロジェクトでのみ再利用する必要があるモジュールについては、再利用されたコードの
  3. sys.path
にパスを追加します。これにより、モジュールを参照することもできます。

絶対パスインポート

すべてのモジュールのインポートは「ルートノード」から開始されます。ルート ノードの場所は sys.path のパスによって決まります。通常、プロジェクトのルート ディレクトリは自動的に sys.path にあります。プログラムをどこでも実行したい場合は、sys.path

import sys,os
BASE_DIR = os.path.dirname(os.path.abspath(__file__))#项目根目录所在的绝对路径sys.path.append(BASE_DIR)import A, B #导入A、B包复制代码

相対パス import

現在のディレクトリからの相対的なモジュールの場所に注意してください。パッケージ内で直接実行することはできません (エラーが報告されます)。ルート ノードがどこにあっても、パッケージ内のモジュールの相対位置は正確です。

#from . import b2 #这种导入方式会报错,只有在包内部直接执行的时候才可以这样导入。import b2#正确b2.print_b2()复制代码

Python モジュールのインポート FAQ

パッケージ名を個別にインポートする場合、パッケージに含まれるすべてのサブモジュールはインポートされません。 解決策: インポートされたパッケージには、他のパッケージのインポートも含まれています。この時点で、最上位層が直接参照できるように、各パッケージの

init
    .py ファイル内のパッケージの下にあるすべてのモジュールをインポートする必要があります。最下層 パッケージのクラスとメソッド
  • init
File

フォルダー内に init

.py がある場合、はこのファイルを意味します フォルダーはパッケージ(package)であり、その配下にある複数のモジュール(module)が全体を形成しており、これらのモジュール(module)は同じパッケージ(package)を通じて他のコードにインポートすることができます。

init.py ファイルは、パッケージを整理し、モジュール間の参照の管理を容易にし、パッケージのインポート動作を制御するために使用されます。 このファイルにはコンテンツを含めることはできません。つまり、空のファイルです (空の場合は、インポート [パッケージ] フォームを使用するだけでは何もできません)。存在する必要があるだけです。マークに相当します。

python3 では、パッケージの下に

init

.py ファイルがない場合でも、インポート パッケージはエラーを報告しませんが、python2 では、ファイルは次の場所にある必要があります。パッケージ、そうでない場合はインポートします。パッケージはエラーを報告します。 #allVariable

all は、これを指定するために使用される重要な変数です。 package (パッケージ) がインポートされる * いつ、どのモジュールが [現在のスコープ] にインポートされるか。

all

リストにないモジュールは、他のプログラムから参照されません。 all は、 all= ['所属する現在のパッケージのモジュール 1 の名前', 'モジュール 1 の名前'] のように書き換えることができます。リスト内のモジュール名が使用されます。

name变量

在包内部直接运行时,包的name == 'main',但是在外部导入包是,可以通过

if __name__ == '__main__':复制代码

来避免实现包内部调试时的逻辑

循环导入

当两个模块A和B之间相互import时,就会出现循环导入的问题,此时程序运行会报错:can not import name xxx,如:

# a.pyprint('from a.py')from b import x

y = 'a'复制代码
# b.pyprint('from b.py')from a import y

x = 'b'复制代码

我们来分析一下这种错误是怎么出现的:

  1. 在sys.modules中查找 符号“module b”;
  2. 如果符号“module b”存在,则获得符号“module b”对应的module对象; 从的dict中获得 符号“x”对应的对象。如果“x”不存在,则抛出异常“ImportError: cannot import name ‘x’”
  3. 如果符号“module b”不存在,则创建一个新的 module对象。不过此时该新module对象的dict为空。然后执行module b.py文件中的语句,填充的dict

因此在a.py中执行from b import x的顺序就是1->3,先引入b,b里面from a import y由相当于执行了a.py,顺序是1->2,因为此时b已经引入所以不会执行3,2中无法找到x对象,因为引入b时还没执行到x='b'这一步,所以报错了

解决办法

  1. 延迟导入,把import语句写在方法/函数里,将它的作用域限制在局部;
  2. 顶层先引入模块,再把from x import y改成import x.y形式;
  3. 其实出现循环引用问题的根本原因是程序设计不合理,每个包都应该由上层使用的模块去导入,而不应该在包与包之间各种相互导入,所以应该更改代码布局,可合并或分离竞争资源;

大型项目中Python模块导入规范

分离模块,将同一类别的模块放在同一目录下,形成类别分明的目录架构,如:

Python モジュールのインポート メカニズムと大規模プロジェクトの仕様を学びます

  1. 每一个模块目录都要写init.py文件,可以同时定义all限定可导入的范围;
  2. 源码根目录可以定义BASE_DIR,限定好根目录路径,启动py文件可以用绝对路径导入各个模块,将必要模块都加入到sys.path中;
  3. 各个服务之间(例如model需要引入common的模块方法),可以通过相对路径引用模块;
  4. 程序设计时避免循环导入,可由调用者(服务文件)作为上层第三方引入需要的各个模块,这样就可以减少各个模块的相互导入。

更多相关免费学习推荐:python视频教程

以上がPython モジュールのインポート メカニズムと大規模プロジェクトの仕様を学びますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.imで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。