Skip to content

Latest commit

 

History

History
243 lines (169 loc) · 7.85 KB

reference_import.md

File metadata and controls

243 lines (169 loc) · 7.85 KB

importについて

module(*.py)のimportの仕方

main.pyMODULE.py内の関数FUNC()や変数VARを使いたい時,以下のように宣言する.

from PATH_OF_PACKAGE import MODULE

RES1 = MODULE.FUNC()
RES2 = MODULE.VAR

もしくは,

from PATH_OF_MODULE import FUNC, VAR

RES1 = FUNC()
RES2 = VAR

PATH_OF_PACKAGEは,MODULE.pyがあるディレクトリの「パス」であり,PATH_OF_MODULEは,MODULE.pyのパスである.

PATHについて

一般的に「パス」の表し方は,

  1. 絶対パス
  2. 相対パス
  3. システムパス の3つがあります.

C:\Users\kotaro\Documents\psp2\foo\bar\pee.py のパスを上記3つのそれぞれで表現してみましょう.

絶対パス

絶対パスは,

C:\Users\kotaro\Documents\psp2\foo\bar\pee.py

です.

最も根源となっているディレクトリ(root,ルート)からどうディレクトリを移動して辿りつくかが書かれている完全な表現です.

相対パス

相対パスは,呼び出し元の絶対パスとの相対関係で表現するものです.

  • 例えば,

    C:\Users\kotaro\Documents\psp2\foo\bar\main.py
    

    から呼び出すのであれば,同じ階層にpee.pyを呼び出すので,相対パスは

    .\pee.py
    

    となります..\は現在地(pwd)を表します.

  • 例えば,

    C:\Users\kotaro\Documents\psp2\foo\main.py
    

    から呼び出すのであれば,同じ階層のbarの下のpee.pyを呼び出すので,現在地.\を使って,

    .\bar\pee.py
    

    となります.

  • 例えば,

    C:\Users\kotaro\Documents\psp2\foo\bar\don\main.py
    

    から呼び出すのであれば,1つ上の階層にあるpee.pyを呼び出すので,

    ..\pee.py
    

    となります...\は1つ上の階層を表します.

システムパス

システムパスは,環境変数が設定されていたときに表現できます.例えば環境変数PATHC:\Users\kotaro\Documents\psp2が含まれていれば,それを絶対パスから削った

foo\bar

がシステムパスです.

ちなみに現在地.\も環境変数に含まれることが多いので,先の「相対パス」に記した例にある.\が含まれているものは.\を省略して構わないことが多いです.(常にそうではないので注意)

ディレクトリとファイル

  • Windowsでは,\をつけてディレクトリの中のファイルを表します.つけてないものは,ディレクトリかファイルそのものです.
  • Mac,*NIXでは,\ではなく/です.

include文に現れるパス

基本的に,

from PATH import FOO

と書きますが,FOOの部分には階層を書かず,PATHに階層を書きます.

pythonでは階層を\/ではなく,.と表現します.

  • 現在地や1つ上の階層を表す表現はありません.つまり.\../などはなく,「相対パス表現」はありません

また,「絶対パス表現」も使えません.したがって,PATH部分には,.を必要に応じて使った「システムパス」のみでパスを表現します.

pythonのシステムパスの環境変数には,次が定義されている.

  • 「実行場所」
    • importが書かれた呼び出し元の.pyファイルの階層
  • 「サイトパッケージ」
    • .venv/lib/pythonX.YY/site-packages/.venvが無ければ,システムのsite-packages
  • 「PYTHONPATH」
    • Windowsの環境変数や,mac/linuxの.bashrcなどで設定
  • 「サイトパッケージ/.pth」
    • 追加したい環境変数を書く

最終的に上記のすべてをまとめたpythonのシステムパス(環境変数)は,次の2行を書いたpythonコードを動かすことで知ることができる.

import sys
print(sys.path)

ちなみに,このリストの順にモジュールを探索するため,このリストにあるパスの下に同じ名前のファイルがある場合,先に見つけられたファイルやディレクトリがimportやfromの対象になる.

sys.path

たとえば

psp2
├── extention
│   └── ext1.py
├── myapp
│   └── main.py

という状況で,psp2/myapp/main.pyからpsp2/extention/ext1.pyをインポートしたいとする.

そのためには,main.pyにおいてsys.pathの直下にextentionやext1.pyがなければならない.

import ext2

としたいなら,sys.pathに〜/psp2/extentionが必要

from extention import ext2

としたいなら,sys.pathに〜/psp2が必要

では,実際に調べてみよう.

myapp/main.py

import sys
print(sys.path)

これを動かしてみよう.

vscodeのコード編集タブの実行ボタンから実行した場合,表示されるパスにextentionの1つ上までの絶対パスは入っているだろうか??おそらく入っておらず,myapp/main.pyからはどうやってもext1.pyはインポートできない.

また,仮想環境の外,つまり,vscodeの編集タブの実行ボタンからではなく,コマンドプロンプトでpy myapp/main.pyとしてみよう.この場合でもsys.pathに,今必要なパスは入っていない.

よって「無理」である.どうしてもextention/ext1.pyをインポートしたいなら,sys.pathで示されたパスの直下にextention/ext1.pyを置く(つまりextentionフォルダを移動する)しか方法がない.手っ取り早いのは,

psp2
├── Readme.md
├── myapp
│   ├── main.py
│   └── extention
│       └── ext1.py
├── poetry.lock
└── pyproject.toml

のようにmain.pyと同じ階層にextentionを移動すれば,from extention import ext1とできる.

どうしても別々のディレクトリにmoduleを置きたいとき,

sys.pathに手動でmoduleのパスを追加する.

import sys               # <- 追加
sys.path.append('..')    # <- main.pyに対するextentionの1つ上の階層の相対パス
from extention import ext1

poetryの場合,sys.path.appendを使わない方法がある.

それは「サイトパッケージ」に,ext1.pyのあるディレクトリextensionの1つ上の階層を加えることである.

(別の言い方をすれば,「extentionをインストールした形に見せかける」といってもよい)

通常の環境では,サイトパッケージは変えられないので無理だが,仮想環境なら好きなように変えられる.

poetryの作る仮想環境のサイトパッケージを変えるには, pyproject.tomltool.poetryに設定を加える.

psp2
├── .venv
├── extention
│   └── ext1.py
├── myapp
│   └── main.py
├── poetry.lock
└── pyproject.toml

という状況のとき,pyproject.tomltool.poetry

packages = [{include = "extention" }]

という行を追加し,psp2の直下にReadme.mdがあることを確認してから,poetry installしてください.

そうすると,vscodeのコード編集タブの実行ボタンから実行した場合(仮想環境の中),表示されるパスにextentionの1つ上までの絶対パスである〜\psp2が追加されていることが確認される.

ちなみに,仮想環境の外ではsys.pathに所望のパスは追加されていない.

importをやめる

from X.Y import a as bしたあとにこのbのインポートをやめたいときは,

del b

すればよい.