5.1 組み込み関数とモジュール

(1/1)
関数のイメージ
Python では、平方根や三角関数のような数学関数のほか、キーボードからデータ入力したり画面にデータ出力する機能も関数として、あらかじめ用意されている。また、import文でモジュールを取り込むことで、カレンダー計算やホームページ解析をするための便利な関数を利用できるようになる。さらに、インターネット上には pipコマンドを使ってインストールすると利用できるようになる多くの便利な外部ライブラリが公開されている。

目次

サンプル・プログラム

関数とは

2次関数のグラフ
一次関数、二次関数、対数関数、三角関数‥‥数学で関数と言えば、\( y = f(x) \) と表し、\( x \) の値が決まれば、\( y \) の値が1つに決まる関係を意味する。
Python を含む多くのプログラミング言語には関数という仕組みが用意されており、\( x \) のことを引数 (ひきすう) 、\( y \) のことを戻り値 (もどりち) と呼ぶ。関数によっては引数を複数指定する場合もあるし、1つも指定しない場合もある。戻り値は1つだが、Pythonではリストのように1つの戻り値の中に複数の値を記入することができる。
ただし、数学の関数の定義どおり、同じ引数に対しては必ず同じ戻り値が返る(リストの中身も同じ)

プログラミング言語における関数は、数学の関数と同じように戻り値を計算して返すものだけでなく、キーボードからデータ入力したり、画面にデータを表示したり、ファイル入出力したり、クラウドと連携するような作用を持つものがある。

組み込み関数

これまで何度か見てきたように、Python にはあらかじめ多くの関数が用意されており、これを組み込み関数と呼ぶ。ここで一覧表に整理しておこう。たくさんあるように見えるが、本シリーズで扱うのは、この一覧表のほんの一部である。
Pythonの組み込み関数一覧
関数戻り値・作用
abs絶対値を返す。
aiter非同期イテレーションが可能なオブジェクトのイテレーターを返す。
allイテラブルオブジェクトの要素がすべて真かどうかを返す。
anext非同期イテレータから次の値を返す。
any要素が1つでも真ならTrueを返す。
ascii与えられた文字列をASCIIコードに変換して返す。
bin与えられた整数を2進数表記の文字列として返す。
bool引数の真偽を判定する。
breakpointデバッグモードに入る。Python 3.7で追加された。
bytearrayデータをバイト列に変換して返す。
bytesbytearrayのイミュータブル版。
callable呼び出し可能オブジェクトであればTrueを返す。
chr与えられた数値をコードとするUnicode文字を返す。
classmethodメソッドをクラスメソッドへ変換する。
compile与えられたPythonコードを内部表現にコンパイルする。
complex与えられた実部と虚部から複素数を返す。
delattr指定したオブジェクトから属性を削除する。
dict辞書を作成する。
dir与えられたオブジェクトの有効な属性リストを返す。
divmod商と剰余を返す。
enumerateenumerateオブジェクトを返す。
eval与えられた文字列をPythonコードとして実行する。
exec与えられた文字列を文として実行する。
filter条件を満たす要素を抽出して返す。
float与えられた文字列を浮動小数に変換して返す。
format文字列の書式を整える。
frozensetfrozensetオブジェクトを返す。
getattr属性の値を返す。
globalsグローバルスコープに定義されている関数や変数を返す。
hasattr属性を持っているかどうかを返す。
hashハッシュ値を返す。
helpヘルプシステムを起動する。
hex与えられた整数を16進数表記の文字列として返す。
idオブジェクトのIDを返す。
inputキーボードから入力した文字列を返す。
int与えられた文字列を整数に変換して返す。
isinstance指定した型またはサブクラスのインスタンスである場合にTrueを返す。
issubclass指定したクラスまたはサブクラスである場合にTrueを返す。
iteriteratorオブジェクトを返す。
lenオブジェクトの長さ(要素の数)を返す。
listリストを作成する。
localsローカルスコープに定義されている関数や変数を返す。
mapシーケンスの構成要素すべてに対して指定した処理を行う。
max与えられた要素の中の最大値を返す。
memoryviewmemoryviewオブジェクトを取得する。
min与えられた要素の中の最小値を返す。
nextイテレータの次の要素を返す。
objectオブジェクトを返す。
oct与えられた整数を8進数表記の文字列として返す。
openファイルをオープンする。
ord与えられた文字のUnicodeコード(整数)を返す。
powべき乗を返す。
print画面に表示する。
propertyproperty属性を返す。
rangerangeオブジェクトを返す。
repr与えられたオブジェクトの文字列表現を返す。
reversed要素を逆順に並べ替える。
round数値を丸めて返す。
setsetオブジェクトを返す。
setattrオブジェクトに属性を追加する。
slice要素の一部を返す。
sorted要素を並べ替えて返す。
staticmethodメソッドを静的メソッドへ変換する。
str与えられたオブジェクトを文字列に変換して返す。
sum要素の合計を返す。
superスーパークラス(親クラス)に関するオブジェクトを返す。
tupleタプルを作成する。
type与えられたオブジェクトの型を返す。
varsクラス内に保持している情報を返す。
zip要素をまとめて返す。
__import__ import文により呼び出される関数。
ここで組み込み関数 divmod を使ったサンプル・プログラム "divmod.py" を作ってみた。除数と被除数を入力すると、divmod を使って商と余りを表示する簡単なプログラムだ。
# メイン・プログラム =======================================================
# キーボードから入力する(文字列).
aStr  = input("除数=")
bStr  = input("被除数=")

# 入力バリデーション(数字(文字列)→数値変換)
try:
	a = validateNumber(aStr, "int", INPUT_NUMBER_MIN, INPUT_NUMBER_MAX, "除数")
	b = validateNumber(bStr, "int", INPUT_NUMBER_MIN, INPUT_NUMBER_MAX, "被除数")

# 失敗したらエラーメッセージを表示してプログラムを終了する.
except ValueError as e:
	dispErrorMessageAndExit(str(e))

# 商と剰余を求める
(div, mod) = divmod(a, b)

# 画面に表示する.
print(f"{a}÷{b}={div}...{mod}")
(div, mod) = divmod(a, b) のうち、a と b が引数で、(div, mod) が戻り値

モジュール

これまで何度か見てきたように、Python には多くの標準ライブラリ外部ライブラリがモジュールとして用意されている。たとえば三角関数を使いたいときは、標準ライブラリ mathimport して、math.sin() のようにして使う。
モジュールによって容易に機能拡張できるのが Python の特長で、このことにより、多くの利用者に受け入れられ、多くの業種で活用されている。
ここでは、標準ライブラリでよく使うものを一覧表に整理しておく。
Pythonの標準ライブラリでよく使うもの
標準ライブラリ内 容
math数学関数
decimal10進数算術演算
fractions有理数(分数を含む)
random疑似乱数
statistics数学的統計関数
datetime日付や時刻(基本)
dateutil日付や時刻
calendarカレンダー計算
string文字列操作
re正規表現
jsonJSONエンコーダーとデコーダー
base64Base16, Base32, Base64, Base85データのエンコード
htmlHTMLデータ処理
xmlXMLデータ処理
webbrowser便利なウェブブラウザコントローラー
httpHTTP通信
sqlite3SQLiteデータベースへのインターフェース
csvCSV形式ファイル読み書き
zlibgzip互換の圧縮
gzipgzipファイルのサポート
sys実行環境に関わるライブラリ
osOSに依存した機能を使うためのライブラリ
atexit終了ハンドラ
argparseコマンラインオプションの解釈
threadingスレッドベースの並列処理
multiprocessingプロセスベースの並列処理
asyncio非同期I/O
socket低水準ネットワークインターフェース
sslソケットオブジェクト用のTLS/SSL ラッパー
email電子メールと MIME 処理のためのパッケージ
標準ライブラリ calendar を使って1ヶ月分の万年カレンダーを表示するプログラムが "monthCalendar.py" である。このように、標準ライブラリを活用することで、簡単に目的のプログラムを書くことができる。
# メイン・プログラム =======================================================
# キーボードから入力する(文字列).
yearStr  = input("西暦年=")
monthStr = input("月=")

# 入力バリデーション(数字(文字列)→数値変換)
try:
	year = validateNumber(yearStr, "int", INPUT_YEAR_MIN, INPUT_YEAR_MAX, "西暦年")
	month = validateNumber(monthStr, "int", INPUT_MONTH_MIN, INPUT_MONTH_MAX, "月")

# 失敗したらエラーメッセージを表示してプログラムを終了する.
except ValueError as e:
	dispErrorMessageAndExit(str(e))

# カレンダーを作成する.
cal = calendar.TextCalendar(calendar.SUNDAY)
monthCalendar = cal.formatmonth(year, month)

#画面に表示する.
print(monthCalendar)
次に外部ラリブラリを使ってみよう。
外部ライブラリ BeautifulSouprequests を使って、指定したサイトの の内容を表示するプログラムが "getHtmlTags1.py" である。
外部ラリブラリを使うときは、まず、pipコマンドを使って外部ライブラリを実行環境にインストールする。
pip install beautifulsoup4
pip install requests
Python には多くの外部ライブラリが出回っており、ネットを検索することで、目的のプログラムを簡単に書けるような外部ライブラリが見つかるだろう。
ただし、外部ライブラリを使うプログラムは、実行環境にも外部ライブラリをインストールする必要があるので、配布時に注意が必要である。
# メイン・プログラム =======================================================
# モジュールをimportする.
try:
	import requests
	from bs4 import BeautifulSoup
except ImportError as e:
	print(f"外部ライブラリをインストールしてください ... {e}")
else:
	response = requests.get(TARGET_URL)
	htmlContents = response.content

# BeautifulSoupを使ってHTMLを解析する. soup = BeautifulSoup(htmlContents.decode("utf-8", "ignore"), "html.parser")
# タグの内容を取得する tags = soup.find(TARGET_TAG, attrs={"name": TARGET_ATTR})
if tags and "content" in tags.attrs: contents = tags["content"] print(contents) else: print("タグが見つかりません")
応用として、プログラム "getHtmlTags1.py" の変数 TARGET_URL を他のサイトにしたり、変数 TARGET_TAGTARGET_ATTR の値を変更して、他のタグの内容を取得できるようにしてみよう。

グラフを描く

Python では関数のグラフを描くことも簡単に出来る。
まず、pipコマンドを使って、グラフ描画の外部ライブラリ Matplotlib と科学技術計算ライブラリ NumPy を導入しよう。
pip install matplotlib
pip install numpy
# メイン・プログラム =======================================================
# モジュールをimportする.
try:
	import numpy as np
	from matplotlib import pyplot as plt
except ImportError as e:
	print(f"外部ライブラリをインストールしてください ... {e}")
else:
	# グラフの描画範囲
	X_MIN = -8.0
	X_MAX = +8.0
	Y_MIN = -8.0
	Y_MAX = +8.0

	# プロットするデータセット(list)を生成
	xList = np.arange(X_MIN, X_MAX, 0.1).tolist()
	yList = [x ** 2 - 3 * x - 4 for x in xList]
	# グラフにプロットするデータ
	plt.plot(xList, yList)

	# 周囲の枠(スパイン)を消す
	for spine in plt.gca().spines.values():
	    spine.set_visible(False)
	# X軸、Y軸を最大値・最小値を設定する
	plt.xlim(-8, +8)
	plt.ylim(-8, +8)
	# X軸、Y軸を描く
	plt.axhline(0, color='black', linewidth=1.0)
	plt.axvline(0, color='black', linewidth=1.0)
	# X軸、Y軸のスケールを合わせる
	plt.gca().set_aspect('equal', adjustable='box')
	# 目盛りを描く
	plt.minorticks_on()
	plt.grid(which='both')
	plt.grid(which='major', linestyle='-', linewidth=0.5, color='gray')
	plt.grid(which='minor', linestyle=':', linewidth=0.5, color='gray')
	# グラフを表示する
	plt.show()
2次関数のグラフ
プログラム "quadraticFunction.py" を実行してみてほしい。左図のように 2次関数 \( x^2 - 3x - 4 \) のグラフを表示する。

まず、numpy.arangeメソッドを使って、X_MIN から X_MAX まで、0.1刻みの小数リスト xList を生成する。
次に、式 [x ** 2 - 3 * x - 4 for x in xList] では、for文 を使って先ほどのリスト xList から1つずつ\( x \)の値を取り出し、2次関数 \( x^2 - 3x - 4 \) に代入して \(y \) の値をリストにして yList に代入する。
リスト xListyList がグラフにプロットする数列となるが、これらを生成するのに繰り返し制御を使う必要はない。

あとは、Matplotlibのグラフ表示を整える部分で、コメントに記しているとおりだ。

練習問題

次回予告

Python では、組み込み関数標準ライブラリ外部ライブラリにないが、よく使う処理を関数に書くことができる。これをユーザー定義関数と呼ぶ。
次回は、作成したユーザー定義関数を使ってグラフを描いたり、書いてはいけない関数について学ぶ。

コラム:標準ライブラリを使ったスクレイピング

本文の "getHtmlTaghs1.py" のような処理をスクレイピングと呼ぶ。BeautifulSoup は優れた外部ライブラリだが、本文の要求であれば、標準ライブラリだけでプログラムを書くことができる。外部ライブラリを使わずに動かすことができれば、プログラム配布先に Python の実行環境がありさえすれば動く。同梱の "getHtmlTaghs2.py" をご覧いただきたい。
# 標準ライブラリをimportする.
import urllib.request
from html.parser import HTMLParser

# スクレイピング対象のURL
TARGET_URL = "https://www.pahoo.org/"
# 取り出したいタグ
TARGET_TAG = "meta"
# タグの属性
TARGET_ATTR = "description"

class scraping(HTMLParser):
	"""スクレイピング・クラス
	
	Note:
		HTMLParserを継承する.
	"""

	def __init__(self, targetTag, targetAttr=""):
		"""コンストラクタ
		
		Args:
			targetTag(str): 取得したいHTMLタグ
		
		Returns:
			None
		"""
		super().__init__()
		self.targetTag  = targetTag
		self.targetAttr = targetAttr
		self.inTargetTag = False
		self.data = []

	def handle_starttag(self, tag, attrs):
		if tag == self.targetTag:
			if (self.targetAttr != ""):
				attrsDict = dict(attrs)
				if attrsDict.get("name") == TARGET_ATTR:
					self.data.append(attrsDict.get("content"))
			else:
				self.inTargetTag = True

	def handle_endtag(self, tag):
		if tag == self.targetTag:
			self.inTargetTag = False

	def handle_data(self, data):
		if self.inTargetTag:
			self.data.append(data)

# メイン・プログラム =======================================================
# HTMLコンテンツを取得する.(UTF-8固定)
response = urllib.request.urlopen(TARGET_URL)
htmlContents = response.read().decode("utf-8")

# HTMLコンテンツを解析する.
scrape = scraping(TARGET_TAG, TARGET_ATTR)
scrape.feed(htmlContents)

# タグの内容を表示する.
print(scrape.data)
(この項おわり)
header