Pythonのinput関数を解剖する【解説記事】

180, 2021-02-11

目次

Pythonのinput関数の使い方

プログラミング言語のPythonにはinput関数という組み込み関数があります。
input関数を使うと標準入力から一行、入力を読み取ることが出来ます。

スポンサーリンク

今回はこのinput関数をおおやけの元で解剖してみたいと思います。

input関数の骨の髄まで皆様にお見せしますよ。
お楽しみください・・・・・・。
具体的には↓を見ていきます。

  • input関数の構造
  • 標準入力とは?
  • input関数で一行読み取る
  • プロンプトを指定して一行読み取る
  • 例外の処理方法
  • input関数のソースコード

input関数の構造

input関数は↓のような構造をしています。

input([prompt])

input関数は最大で1つの引数を取り、1つの返り値を返します。
引数promptは省略することが可能です。

prompt(第1引数: オプショナル)

input()の第1引数に文字列を渡すと、input()は入力の読み取り前にこの文字列を標準出力に出力します。
このpromptは入力時のプロンプトとして機能します。
たとえば↓のようにpromptに文字列を指定すると、

input('入力してください > ')

実際の動作は↓のようになります。

入力してください > 

「入力してください > 」という文字列が標準出力に出力され、その直後に標準入力の読み取りがはじまります。

返り値(文字列)

input()の返り値は文字列です。
これは標準入力から読み取られた一行の入力です。
末尾の改行は取り除かれています。

標準入力とは?

input関数は「標準入力」から入力を一行読み取りますが、この標準入力とはいったいなんなのでしょうか。
標準入力とは、標準で読み込まれる入力のことで、通常はパソコンならキーボードを指します。
Pythonにおける標準入力を表すオブジェクトはsys.stdinオブジェクトがそうです。
sys.stdinオブジェクトはsysモジュールをインポートすると利用可能になります。

import sys

sys.stdinはキーボードと繋がっているオブジェクトです。
このオブジェクトのread()などのメソッドを使うと、キーボードから入力を読み取ることが出来ます。

sys.stdin.read()

input関数も内部ではstdinオブジェクトから入力を読み取っています。
ただこれは実装によるファイルオブジェクトです。
たとえばCPythonによる実装ならinput()はCのstdinオブジェクトを参照します。

sys.stdinを使えばinput()のクローンを作ることも可能です。
ただその場合はPythonによる実装になるので、動作は組み込みのinput()のほうが速いと思われます。

input関数で一行読み取る

それではinput()で標準入力から一行、入力を読み取ってみます。
↓のようにコードを書きます。

line = input()
print(line)

↑のコードを実行すると、何もない画面上で入力待ちになります。
適当な文字列をキーボードから打ち込みエンターキーを押すと入力が完了します。
その結果はinput()の返り値として返ってきて↑のline変数に格納されます。

よって「Hello, World!」と入力すると↓のように出力されます。

Hello, World!

プロンプトを指定して一行読み取る

input()の第1引数にプロンプトを表す文字列を渡してinput()を実行します。

food = input('好きな食べ物は? > ')
print(food)

↑のコードを実行すると↓のようにプロンプトが表示され、入力がうながされます。

好きな食べ物は? > 

ここでたとえば「桃」と入力すると、↓のように出力されます。

↑のように変数foodには「桃」という文字列が格納されます。

例外の処理方法

標準入力ではさまざまな信号をキーボードから送ることができます。
それはたとえば「EOFの送信」や「プログラムの停止」などの信号です。
この信号はinput()に伝わり、input()はそれらの信号を例外として外に送出します。

つまりinput()が送出する例外をコントロールすればそれらの信号を扱うことが出来るということになります。
代表的な例外として↓があります。

  • EOFError
  • KeyboardInterrupt

EOFErrorは入力がEOF(End Of File)に達したときに送出される例外です。
なぜEOFかというと標準入力は内部的にはファイルオブジェクトとして定義されているからです。
ファイルの終端、つまりEOFに入力が達したらそれ以上読み込むものは無いので、このような例外が送出されるということです。

KeyboardInterruptはキーボードから「Ctrl+C」などの入力がされたときに送出される例外です。
Ctrl+C」は実行中のプログラムを中断したい時に入力されます。
キーボード左下の「Ctrl」キーと「C」キーを同時押しすると入力できます。

これらの例外はinput()から送出されます。
よってこれらの例外をハンドリングするには↓のようにコードを書きます。

try:
    line = input()
except EOFError:
    print('EOFを検出しました')
except KeyboardInterrupt:
    print('Ctrl+Cを検出しました')
else:
    print(line)

↑のコードを実行し、入力にCtrl+D(Windowsの場合はCtrl+Z)を入力すると「EOFを検出しました」という出力が得られます。
また、入力でCtrl+Cを入力すると「Ctrl+Cを検出しました」という出力が得られます。

input関数のソースコード

Python3におけるinput関数の実装はどうなっているのでしょうか。
ここではCPythonによる実装を取り上げたいと思います。
CPythonではinput()の実装は↓のようになっています。

↑のコードを見ると最初の方でstdinオブジェクトをfinとして取得しているのがわかります。
finNULLまたはNoneだった場合はinput()はRuntimErrorを発生させます。
その時のエラーメッセージは「input(): lost sys.stdin」になります。

またコメントで「If we're interactive, use (GNU) readline」と書かれていることから、入力がインタラクティブ、つまり対話的な場合はinput()はGNU readlineを使っていることがわかりますが、GNU readlineを呼び出してる部分は見当たらず、あるのはPyOS_Readline()の呼び出しだけです。

input()内で実際に行の読み取りを行っているのはPyOS_Readline()です。

Pythonの行入力がどのような処理になって以下知りたい場合はこの関数を掘っていけば良さそうですね。
ちなみに掘っていくと最終的にはfgets()などのCのAPIに当たります。
GNU readlineを使っている部分の分岐はちょっとわかりませんでした。

おわりに

今回はPythonの組み込み関数input()を解剖してみました。
input()の骨の髄までみなさまにお見せすることを目的とする記事でしたがいかがでしたでしょうか。
よろしければブックマークをお願いします・・・・・・。

input()で入力を受け取ろう

スポンサーリンク

投稿者名です。64字以内で入力してください。

必要な場合はEメールアドレスを入力してください(全体に公開されます)。

投稿する内容です。