LoginSignup
2
2

More than 3 years have passed since last update.

pythonのimportをはじめて勉強してたときのメモ

Last updated at Posted at 2019-07-21

まだよくわかってない

__name__ とかと、importの基本

importされる人をモジュールと呼ぶらしい。

同じ階層に置く

$ ls -l
-rw-r--r--  1 book  staff  60 Apr  6 00:34 app.py
-rw-r--r--  1 book  staff  58 Apr  6 00:35 run.py
app.py
def app():
  print 123

if __name__ == "__main__":
  app()
$ python app.py 
123

これをimportする

run.py
import app
book:py book$ python run.py 

何もでない。__name__のとこがimportだと実行されない。

実行部を足すと出る。

run.py
import app

if __name__ == "__main__":
  app.app()
$ python run.py 
123

import app は、 import (同じ階層にある)app(.pyと言うなのファイル) として解釈される。

*pythonで実行されたscriptは、同じ階層にある .py ファイルをファイル名から拡張子を除いた名前で import することができる。
なんでやねん。import app.py のほうが2万倍わかりやすいやん・・・

importにはimportとfrom - import - の2種類あって、階層をどこからたぐるかが違う。
↑の例ではapp.pyをappと言う名で読み込んでいる。

app.py
 |- def app

これをこうだとすると、

app.py(1)
 |- def app(2)

import app(1) で from app(1) import app(2) ってことになるらしい。
だから app.app() は app(1).app(2)() で app() は app(2) ってことになる。
いちいちapp.app() てapp.をつけるの面土井時は、fromを使う。

run.py
from app import app

if __name__ == "__main__":
  app()
$ python run.py 
123

モジュールの階層化

app.pyを ./modules フォルダに入れてみる。

.
├── modules
│   ├── app.py
└── run.py

こうすると走らない。importは同じ階層にしか効かない。不便な奴だ・・・・pathとfile名でincludeできるphpを見習って欲しい・・・・

サブディレクトリをimportしたい場合はおまじないを使う。

.
├── modules
│   ├── __init__.py
│   ├── app.py
└── run.py

pythonは、実行されたscriptと同じ階層にあるdirectoryを探して、その中に __init__.py があると、其のフォルダの中をimport対象として認識する。
__init__.pyは空でいい。 $ touch __init__.py でいい。なんだこの残念仕様。まるでapacheの.htaccessみたいな。残念な仕様だ。

サブディレクトリになると、importはこうなる。

run.py
import modules.app

if __name__ == "__main__":
  modules.app.app()
$ python run.py 
123

modules.app.app()って残念すぎません? サブディレクトリになるとこうしてどんどん深くなっていくので、みんなfromを使い出す。

run.py
from modules.app import app    <---- [modulesディレクトリ内の app.py] の中の [def app():] をimportしている

if __name__ == "__main__":
  app()
$ python run.py 
123

わかってきた。

__init__.py とは

__init__.pyにはpythonコードが書ける。

modules/__init__.py
print "__init__desu"
run.py
import modules.app
$ python run.py 
__init__desu

__init__.py でimportできるわけではない

scriptは其の周りの__init__.pyも実行してしまうのなら、ここでipmortすれば他に書かなくてもいいんじゃないか、って思ったけどだめだった

modules/__init__.py
print "__init__desu"
import os
book:py book$ cat modules/app.py
def app():
  print 123

if __name__ == "__main__":
  app()
  print os.listdir() 

book:py book$ cat run.py 
import modules.app

if __name__ == "__main__":
  print os.listdir()
modules/app.py
def app():
  print 123

if __name__ == "__main__":
  app()
  print os.listdir() 
$ python run.py 
__init__desu
Traceback (most recent call last):
  File "run.py", line 4, in <module>
    print os.listdir()
NameError: name 'os' is not defined

ここらへんがphperには辛い事実。pythonのimportは.pyひとつひとつ独立してる。一回動き始めたscriptはあっちでincludeしてればこっちでも使えるが通用しない。辛い・・・

__init__.py に変数がかけるわけでもない?

global とかやっても全然使えなかった。辛い

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2