今さらPython3 (34) - モジュール

第5章に突入。

入門 Python 3

入門 Python 3

その前に、オライリー英語版サイトには書評というか、購入者のレビューが載っているんですけど、この記事を書いている時点で星3.8という評価になっています。

shop.oreilly.com

とは言え、CONSとされている指摘の大半は、too basicというもの。本書が簡単すぎるというのですが、本のタイトルにIntroducing(入門)と入っているのだから、的外れな指摘じゃないかなとも思うんですよね。実際、自分も入門者ではないですが、いくつか目新しい発見があり、基礎からやり直して良かったなと実感し始めているところです。

インタプリタからの卒業?

>>> print("This interactive snippet works.")
This interactive snippet works.

今度はファイルを作るところから始めるようになる訳ですね。その前にPATHを通しておかないと面倒なことになると思うので、一応リンクをここに。

deutschina.hatenablog.com

まずは、test1.pyというテキストファイルを作り、その中にこんなロジックを書く。

>>> print("This interactive snippet works.")
This interactive snippet works.

教科書通りだと、こうやって実行する。

$ python3 test.py

でも、面倒なので自分の場合は、PyCharmのエディタから直接実行してみる。

/Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4 /Users/ken/PycharmProjects/IntroducingPython3/test1.py
This standalone program works!

Process finished with exit code 0

こういう結果が得られる。

import sys
print('Program arguments:', sys.argv)

上のソースコードをtest2.pyで作成して実行。

/Library/Frameworks/Python.framework/Versions/3.4/bin/python3.4 /Users/ken/PycharmProjects/IntroducingPython3/test2.py
Program arguments: ['/Users/ken/PycharmProjects/IntroducingPython3/test2.py'||

Process finished with exit code 0

こうなる。でも、教科書通りコマンドラインから動かそう。Python自体にはPathが通っているはず(じゃないとこの本のここまでたどり着けない)ので、先にpyファイルを保存してあるディレクトリに移動してから、コマンドを叩けば良い。

C:\Users\xxxxxxx > cd PycharmProjects\IntroducingPython3
C:\Users\xxxxxxx\PycharmProjects\IntroducingPython3>python test2.py
Program arguments: ['test2.py']

C:\Users\xxxxxxx\PycharmProjects\IntroducingPython3>python test2.py ura la la
Program arguments: ['test2.py', 'ura', 'la', 'la']

これは、Mac OSXとか他の環境でも一緒でしょ。

Importする

インポートするときは、ファイル名拡張子(.py)を取り除いた名称で呼び出すと。

とりあえずweather.pyというファイルを作る。ソースはこんな感じ。

import report

description = report.get_description()
print("Today's weather:", description)

この中でreportというのをimportしているから、report.pyというのも作る。

def get_description():  # see the docstring below?
    """
    Return random weather, just like the pros
    """
    from random import choice
    possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who know']
    return choice(possibilities)

で、weather.pyを実行してみる。

C:\Users\xxxxxx\PycharmProjects\IntroducingPython3>python weather.py
Today's weather: snow

C:\Users\xxxxxx\PycharmProjects\IntroducingPython3>python weather.py
Today's weather: sleet

C:\Users\xxxxxx\PycharmProjects\IntroducingPython3>python weather.py
Today's weather: who knows

C:\Users\xxxxxx\PycharmProjects\IntroducingPython3>python weather.py
Today's weather: snow

C:\Users\xxxxxx\PycharmProjects\IntroducingPython3>python weather.py
Today's weather: fog

C:\Users\xxxxxx\PycharmProjects\IntroducingPython3>python weather.py
Today's weather: sleet

C:\Users\xxxxxx\PycharmProjects\IntroducingPython3>python weather.py
Today's weather: snow

C:\Users\xxxxxx\PycharmProjects\IntroducingPython3>python weather.py
Today's weather: sun

晴れが出るまで粘っただけw。

importの呼び方という意味では、weather.pyのいの一番に呼んでいるimport reportと、関数get_descriptionの中で乱数用の関数を呼んでいるfrom random import choiceがあると。ファイル全体を呼ぶのと関数名を選択して呼んでいるという違いもありますよと。

>>> def get_description():
...     import random
...     possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows']
...     return random.choice(possibilities)
...
>>> get_description()
'sleet'
>>> get_description()
'sleet'
>>> get_description()
'rain'
>>> get_description()
'rain'
>>> get_description()
'who knows'
>>>

このインタプリタでやった例だと、choiceが含まれているrandom全体をimportしていて、実際にchoiceを使う時になって、random.choice()という呼び出し方をしている。

もちろん、import randomを外に出してあげても良いわけで、

>>> import random
>>> def get_description2():
...     possibilities = ['sunny', 'cloudy', 'rainy']
...     return random.choice(possibilities)
...
>>> get_description2()
'sunny'
>>> get_description2()
'sunny'
>>> get_description2()
'sunny'
>>> get_description2()
'cloudy'
>>>

このあたりは、変数のスコープと同じ考え方で良いのではないかと。他の関数とかで使いたいなら、外側でインポートして使い回せば良いし、使い回す必要がないなら、関数の中で毎回importすれば良いという話ですね。実際の開発現場では、この辺りは、開発規約で決まっている話かと思います。

名前が長いので

as なんちゃらで呼ぶ方法もあります。(エリアスと呼ぶらしい)

import report as wr

description = wr.get_description()
print("Today's weather:", description)

この中では、reportはwrと呼ばれていますよと理解すれば良し。asなんちゃらを使えるのはモジュール(ファイル名)だけではなく、

from report import get_description as do_it

description = do_it()
print("Today's weather:", description)

関数名でも良いですよってことですね。分かります。

from report import get_description

description = get_description()
print("Today's weather:", description)

from report import get_description as do_it

description = do_it()
print("Today's weather:", description)

description = get_description()
print("Today's weather:", description)

importは別に何回呼んでも怒られないのは経験上知ってます。わざと上みたいにやることは実際にはないと思うけど。

ここで来たかPathよ

importするためには、モジュールがpathに入っていないとダメだよねという話。

>>> import sys
>>> for place in sys.path:
...     print(place)
...

C:\Python34\lib\site-packages\setuptools-18.5-py3.4.egg
C:\Python34\lib\site-packages\ipython-4.0.0-py3.4.egg
C:\Python34\lib\site-packages\traitlets-4.1.0b1-py3.4.egg
C:\Python34\lib\site-packages\simplegeneric-0.8.1-py3.4.egg
C:\Python34\lib\site-packages\pickleshare-0.5-py3.4.egg
C:\Python34\lib\site-packages\decorator-4.0.4-py3.4.egg
C:\Python34\lib\site-packages\ipython_genutils-0.1.0-py3.4.egg
C:\Python34\lib\site-packages\path.py-8.1.2-py3.4.egg
C:\WINDOWS\system32\python34.zip
C:\Python34\DLLs
C:\Python34\lib
C:\Python34
C:\Python34\lib\site-packages
>>>

この記事はwindows PC環境でやっているので、こういう出方になりました。Max OSX環境だとまた見え方が違うはず。本にも書いてあるけど、1行目は空白、つまりカレントディレクトリ。さっき、コマンドプロンプトで自らファイルのある場所に移動していたので、「report.py?そんなファイル知らねぇよ」と怒られなかった訳ですね。

(つづく)