importとfrom〜importについてもうすこし

モジュールのインポートについては以前学びましたがいまいち理解が追いついていなかったのでもっかいおさらい。


importで読み込んだものがなんなのか、typeで調べてみます。

helloworld関数を持つtest.pyを用意します。

# -- test.py --
def helloworld():
    print("Hello World!")
# -- main.py --
import test

print(type(test))
$ py main.py
<class 'module'>

moduleですね。

次にfooというディレクトリを置いてそれをimportしてみます。

import foo

print(type(foo))
$ py main.py
<class 'module'>

これもmoduleですね。importに指定できるのはファイルやディレクトリのみでそれらはmoduleとして扱われます。

importに指定できるのはこのmoduleのみです。それ以外は例外となります。

import test.helloworld
$ py main.py
Traceback (most recent call last):
  File "main.py", line 4, in <module>
    import test.helloworld
ModuleNotFoundError: No module named 'test.helloworld'; 'test' is not a package

helloworldは関数なので例外になる感じですね。


次はfrom〜importですが、コレも基本的にはimportと同じです。

違う点はfromに指定できるのがmoduleでimportには関数やmodule等何でも指定できるといったかんじですか。

from test import helloworld

helloworld()
$ py main.py
Hello World!


まとめとして

  • importの場合、moduleのみ指定できる
  • from〜importの場合、fromにはmoduleのみ指定、importには関数やmodule等何でも指定できる


ってかんじですかね。これだけ覚えておけば今後迷うことはないかなと。

pipによるパッケージのインストール

世に公開されているたくさんのパッケージをインストールしたりなんかしたりするためのツールです。

今回は試しにrequestsってのを入れてみることにする。

$ pip install requests

これだけでrequestsというパッケージが使用可能となる。

import requests

url = 'http://localhost/test.php';

res = requests.get(url) # urlに通信して結果を得る
print(vars(res))

今後はpipを使用してさまざまなパッケージを利用していきます。

「(?P・・・)」による名前付き後方参照

入門Python3 7.1.3.8


「(?P<名前>・・・)」という構文を使うと名前付きの後方参照ができます。参照するには「\g<名前>」と書きます。

import re

str1 = "aa1bb2cc3bb4"
str2  = re.sub('(?P<foo>\d+)',r'[\g<foo>]',str1)
print(str2)
$ py main.py
aa[1]bb[2]cc[3]bb[4]


またgroupでの引数にもこの名前で値を得ることが可能となります。

import re

str1 = "aaa123bbb"
r = re.search('(?P<foo>\d+)',str1)

if r:
    print(r.group('foo')) # fooで取得することができる
    print(r.group(1))     # もちろん1でも同様に取得可能
$ py main.py
123
123

subによる文字列の置換

入門Python3 7.1.5


subで文字列の置換ができます。

import re
str1 = "aa11bb22cc33bb"
str2  = re.sub(r'\d+',':',str1)
print(str2)
$ py main.py
aa:bb:cc:bb


グループ化して後方参照することもできます。

import re
str1 = "aa11bb22cc33bb"
str2  = re.sub(r'(\d+)',r'[\1]',str1)
print(str2)
$ py main.py
aa[11]bb[22]cc[33]bb


また関数を指定して後方参照を関数で受け取ることもできます。関数にはMatchオブジェクトが来ます。

import re

def foo (match):
    '''数値を二倍にして置換する'''
    return str(int(match.group()) * 2)

str1 = "a1b2c3d4"
str2  = re.sub(r'\d',foo,str1)
print(str2)
$ py main.py
a2b4c6d8

リストから空要素を除去する

例えばsplitなどで以下のようなリストができることがあります。

import re
str1 = "a:b:c:d::"
r = re.split(r':',str1)
print(r)
$ py main.py
['a', 'b', 'c', 'd', '', '']

このとき空文字の要素だけ除去された状態のリストを得たい場合、リスト内包表記を使うと便利です。

import re
str1 = "a:b:c:d::"
r = [i for i in re.split(r':',str1) if i != '']
print(r)
$ py main.py
['a', 'b', 'c', 'd']

ちなみに当初remove('')でやろうとしたのですが、空文字がひとつしか削除されない上に、空文字が無い場合は例外まで出るので使えたものじゃありませんでした。

splitによる文字列の分割

入門Python3 7.1.4


splitで文字列を分割しリスト化することができます。

import re

str1 = "a:b:c:d"
r = re.split(r':',str1)
print(r)
$ py main.py
['a', 'b', 'c', 'd']


もちろん正規表現で分割もできます。

import re
str1 = "a11b22c33d"
r = re.split(r'\d+',str1)
print(r)
$ py main.py
['a', 'b', 'c', 'd']

文字列中のバックスラッシュについて

文字列の前にrをつけるとバックスラッシュを特殊文字として展開しないようになります。

str1 = "a\tb"
str2 = r"a\tb"

print(str1)
print(str2)
$ py main.py
a	b
a\tb


主に正規表現を書くときに使うと便利っぽいです。