前回の記事の続きです。
7章 入出力
出題数 1/ 40問(2.5%)
7.1 入力と出力
- 標準入力:キーボードやファイルなどからデータを入力(
input()
関数など) - 標準出力:コンソールへの出力など(
print()
関数など) - 標準エラー出力:エラーメッセージの出力
7.2 input()関数
- キーボードからの入力値を受け取る
- 受け取ったデータは文字列に変換される
-
int()
、float()
、complex()
などの関数で数値のデータ型に変換可能
>>> price = int(input('値段を入力してください:'))
値段を入力してください:100
>>> print('税込み', round(price * 1.1),'円です。')
税込み 110 円です。
>>> price = int(input('値段を入力してください:'))
値段を入力してください:100.3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '100.3'
>>> price = int(input('値段を入力してください:'))
値段を入力してください:i
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'i'
7.3 print()関数、sys.stdout.write()
-
print()
関数- 内部で
str()
関数を使って文字列に変換して出力 - 末尾に自動で改行が入る
※print()
関数を使うとNoneも出力できる
- 内部で
-
sys.stdout.write()
-
sys.stdout
は、標準出力されたテキストファイル - 改行が入らずに一行で結果が出力
-
str()
で文字列に変換しなかった場合はエラーが発生
-
例
import sys
nodata = None
print('あいうえお')
print(1 + 2)
print(nodata)
sys.stdout.write('あいうえお')
sys.stdout.write(str(1 + 2))
sys.stdout.write(str(nodata))
実行結果
あいうえお
3
None
あいうえお3None
7.4 標準出力のプロセス
- 文字列をエンコードしてからデコードする処理が含まれる
- デコードを行うには、先にエンコードされるため、文字列に変換しておく必要あり
(エンコード:文字列→バイト列、デコード:バイト列→文字列)
※符号化形式は、以下のコマンドで確認
>>> sys.stdout.encoding
'utf-8'
7.5 str()関数、repr()関数
-
str()
関数:オブジェクトを人間が理解しやすい文字列に変換する -
repr()
関数:オブジェクトをデバッグしやすい文字列(インタープリタに読める表現)に変換する
※数値オブジェクトの場合は、両者とも同じ結果が出力
>>> name = 'abc'
>>> print(str(name))
abc
>>> print(repr(name))
'abc'
>>> a = 1
>>> print(str(a))
1
>>> print(repr(a))
1
>>> import datetime
>>> dt = datetime. datetime (2023, 5, 29, 10, 30, 20 , 1230)
>>> print(str(dt))
2023-05-29 10:30:20.001230
>>> print(repr(dt))
datetime.datetime(2023, 5, 29, 10, 30, 20, 1230)
7.6 stringモジュール
- 標準モジュール
-
Template
クラスで文字列を置き換え -
substitute
メソッドで出力
-
>>> from string import Template
>>> question = '1'
>>> answer = 'B'
>>> t = Template('問題${first}の答えは${second}です。')
>>> print(t.substitute(first=question, second=answer))
問題1の答えはBです。
7.7 文字列のフォーマット
- 各フォーマット
-
Python2.6以前:
%
(モジュロ)演算子によるフォーマット-
%s
:文字列 -
%10s
:最小フィールド幅を指定 -
%-10s
:-
でフィールド幅を指定して左詰に -
%d
:符号付き10進整数 -
%f
:10進浮動小数点数(デフォルトの精度は6) -
%15.2f
:最小フィールド幅15、小数点以下の桁数2
-
-
Python2.6-3.6:
format()
メソッドによるフォーマット- コロン(
:
)の左側にインデックス、右側にオプションを指定-
:s
:文字列 -
:
:指定なし(数値、文字列どちらでもエラー未発生) -
:*^15
:中寄せ、残りを*で埋める、15文字 -
:*<15
:左寄せ、残りを*で埋める、15文字 -
:0>10
:右寄せ、残りを0で埋める、10文字 -
:^10
:中寄せ、残りを空白で埋める、10文字 -
:d
:符号付き10進整数 -
:,d
:3桁ごとにカンマで区切る、符号付き10進整数 -
:+,d
:正の数(+
)、3桁ごとにカンマで区切る、符号付き10進整数 -
:f
:10進浮動小数点数(デフォルトの精度は6) -
:.3f
:10進浮動小数点数(精度3) -
:0^12.3f
:中寄せ、残りを0で埋める、最小フィールド幅12、10進浮動小数点数(精度3) -
:0>12.3f
:右寄せ、残りを0で埋める、最小フィールド幅12、10進浮動小数点数(精度3) -
:0<12.3f
:左寄せ、残りを0で埋める、最小フィールド幅12、10進浮動小数点数(精度3) -
:0=12.3f
:右寄せ、残りを0で埋める、最小フィールド幅12、10進浮動小数点数(精度3)
-
- コロン(
-
Python3.6以降:f-Stringによるフォーマット
- コロン(
:
)の左側に値、右側にオプションを指定 -
{}
内に計算式を書ける
- コロン(
-
>>> item = '本'
>>> price = 1000
>>> '%sは%d円です。' % (item, price)
'本は1000円です。'
>>> print('%7.3f' % price)
1000.000
>>> print('%8.3f' % price)
1000.000
>>> print('%9.3f' % price)
1000.000
>>> print('%9.2f' % price)
1000.00
>>> print('%s' % ('abc'))
abc
>>> print('%10s' % ('abc'))
abc
>>> print('%-10s' % ('abc'))
abc
>>> print('%d' % (123.456789123))
123
>>> print('%f' % (123.456789123))
123.456789
>>> print('%15.2f' % (123.456789123))
123.46
>>> '{}は{}円です。'.format(item, price)
'本は1000円です。'
>>> '{item2}は{price2}円です。'.format(item2='筆箱', price2='200')
'筆箱は200円です。'
>>> x = 'abc'
>>> y = 'def'
>>> print('{0} {1}'.format(x, y))
abc def
>>> print('{1} {0}'.format(x, y))
def abc
>>> p = [300, 100, 200]
>>> print('A:{0[2]} B:{0[0]} C:{0[1]}'.format(p))
A:200 B:300 C:100
>>> print('{:s}'.format('abc'))
abc
>>> print('{:s}'.format(123))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 's' for object of type 'int'
>>> print('{:}'.format('abc'))
abc
>>> print('{:}'.format(123))
123
>>> print('{:*^15}'.format('abc'))
******abc******
>>> print('{:*<15}'.format('abc'))
abc************
>>> print('{:0>10}'.format('abc'))
0000000abc
>>> print('{:^10}'.format('abc'))
abc
>>> print('{:d}'.format(123.45))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'd' for object of type 'float'
>>> print('{:d}'.format(123))
123
>>> print('{:d}'.format(123,45))
123
>>> print('{:,d}'.format(100000))
100,000
>>> print('{:,d}'.format(1000000))
1,000,000
>>> print('{:,d}'.format(10000000))
10,000,000
>>> print('{:,d}'.format(100000000))
100,000,000
>>> print('{:+,d}'.format(100000))
+100,000
>>> print('{:+,d}'.format(1000000))
+1,000,000
>>> print('{:+,d}'.format(10000000))
+10,000,000
>>> print('{:+,d}'.format(100000000))
+100,000,000
>>> print('{:f}'.format(100))
100.000000
>>> print('{:.3f}'.format(100))
100.000
>>> print('{:0^12.3f}'.format(100))
00100.000000
>>> print('{:0>12.3f}'.format(100))
00000100.000
>>> print('{:0<12.3f}'.format(100))
100.00000000
>>> print('{:0=12.3f}'.format(100))
00000100.000
>>> f'{item}は{price}円です。'
'本は1000円です。'
>>> F'{item}は{price}円です。'
'本は1000円です。'
>>> discount = 0.2
>>> f'{item}は{price * (1 - discount)}円です。'
'本は800.0円です。'
>>> f'{item}は{price * (1 - discount):d}円です。'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'd' for object of type 'float'
>>> f'{item}は{price * (1 - discount):f}円です。'
'本は800.000000円です。'
>>> f'{item}は{round(price * (1 - discount))}円です。'
'本は800円です。'
- 手作業でのフォーマット
-
rjust()
メソッド -
ljust()
メソッド -
center()
メソッド -
zfill()
メソッド
-
>>> name = 'abcdefg'
>>> name.rjust(10, '_')
'___abcdefg'
>>> name.ljust(10, '_')
'abcdefg___'
>>> name.center(10, '_')
'_abcdefg__'
>>> '20'.zfill(7)
'0000020'
>>> '-20'.zfill(7)
'-000020'
7.8 ファイルオブジェクト
-
ファイルを読み書きするためのデータ
-
open()
やwrite()
を使用
-
-
ファイルを開く(
open()
)-
変数 = open('ファイル名', 'モード', 'エンコーディング')
-
エンコーディング:指定なしの場合はプラットフォーム依存
-
モード:以下の①~③を組み合わせた形で使用(指定なしの場合は
r
)①
-
r
:読み込み用(ファイルがない場合はエラー) -
w
:書き込み用(上書き) -
a
:書き込み用(追記) -
x
:書き込み用(新規ファイル生成、ファイルが既にある場合はエラー)
②
-
t
:テキストモード(内容をテキストとみなして処理) -
b
:バイナリモード(バイト列のまま処理、エンコーディングは指定できない)
③
-
+
:更新用( 読み書き両方を指定)
-
-
>>> f = open('abc.txt', 'wb+')
>>> f.close()
>>> f = open('abc.txt', 'r', encoding='shift_jis')
>>> f.close()
>>> f = open('abc.txt', 'rb', encoding='shift_jis')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: binary mode doesn't take an encoding argument
- ファイルを開く(
with open()
)- 処理中に例外が発生しても必ず閉じる
-
with
キーワードを使わない場合はclose()
7.9 ファイルオブジェクトのメソッド
- ファイルの内容を読み込む
-
read(文字数)
- 指定した文字数のみ
- 文字数がない場合や負の数のときはすべて返す
- 終端に達した後は空の文字列
''
を返す
-
readline()
- 1行ずつ
-
readlines()
- 行ごとのリスト
-
for line in 変数:
- 1行ずつ
-
>>> with open("sample1.txt", encoding="UTF-8") as f:
... text3 = f.read(3)
...
>>> text3
'あいう'
>>> with open("sample1.txt", encoding="UTF-8") as f:
... text = f.read()
...
>>> text
'あいうえお\nかきくけこ\nさしすせそ'
>>> print(text)
あいうえお
かきくけこ
さしすせそ
>>> f = open("sample1.txt", encoding="UTF-8")
>>> f.readline()
'あいうえお\n'
>>> f.readline()
'かきくけこ\n'
>>> f.readline()
'さしすせそ'
>>> f.readline()
''
>>> f.close()
>>> with open("sample1.txt", encoding="UTF-8") as f:
... text_list = f.readlines()
...
>>> text_list
['あいうえお\n', 'かきくけこ\n', 'さしすせそ']
>>> with open("sample1.txt", encoding="UTF-8") as f:
... for line in f:
... print(line, end="")
...
あいうえお
かきくけこ
さしすせそ>>>
- ファイルに内容を書き込む:
write(文字列)
-
write()
メソッド書き込んだ時点では、メモリに一時保管されているだけ - ファイルを閉じた時点で書き込みが行われる
- 書き込まれた文字数を返す
- 文字列以外(数値データなど)を書き込むとTypeErrorになる
-
>>> fw = open('sample2.txt', 'w')
>>> fw.write(5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: write() argument must be str, not int
>>> fw.write('abcdefg')
7
>>> fw.close()
- 先頭文字から数えた現在位置を扱う
-
tell()
- バイナリモードではファイルの先頭から数えたバイト数を返す
- テキストモードでは不明瞭な値を返す(全角は2バイト、半角は1バイト)
-
seek(オフセット値, 基準点)
- ファイルの特定の位置に移動し、先頭からのバイト数を返す
-
seek
の第2引数
0:ファイルの先頭
1:現在位置
2:ファイルの末尾
※テキストモードの場合、基準点は0のみ有効(例外として、唯一の有効なオフセット値はf.tell()
から返された値か0のいずれか)
-
>>> f = open('sample2.txt', 'rb+')
>>> f.read(2)
b'ab'
>>> f.read(3)
b'cde'
>>> f.tell()
5
>>> f.read(1)
b'f'
>>> f.tell()
6
>>> f.read()
b'g'
>>> f.read()
b''
>>> f.seek(2, 0)
2
>>> f.read(1)
b'c'
>>> f.seek(2, 1)
5
>>> f.read()
b'fg'
>>> f.seek(-3, 2)
4
>>> f.read(1)
b'e'
>>> f.close()
>>> f = open('sample2.txt', 'r')
>>> f.seek(2, 1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
io.UnsupportedOperation: can't do nonzero cur-relative seeks
>>> f.seek(0, 1)
0
>>> f.seek(0, 2)
7
>>> f.seek(-3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: negative seek position -3
>>> f.close()
7.10 jsonファイルの操作
-
シリアライズ(直列化)
- 複数の要素を一列に並べる操作や処理
-
dump()
関数またはdumps()
関数によりデータ構造オブジェクトをJSON文字列に変換json.dump(データ構造オブジェクト, ファイルオブジェクト)
-
json.dumps(データ構造オブジェクト)
※サポートしていない型は拡張する必要あり
-
デシアライズ
- シリアライズされたデータを元のオブジェクトに復元する処理
-
load()
関数またはloads()
関数によりJSON文字列をデータ構造オブジェクトに変換json.load(ファイルオブジェクト)
json.loads(文字列)
>>> import json
>>> data = [3, "f"]
>>> json.dumps(data)
'[3, "f"]'
>>> type(data)
<class 'list'>
>>> type(json.dumps(data))
<class 'str'>
>>> f = open("sample4.json", 'w')
>>> data = [3, "f"]
>>> json.dump(data, f)
>>> f.close()
>>> with open('sample4.json', 'r') as f:
... data2 = json.load(f)
...
>>> data2
[3, 'f']
>>> type(data2)
<class 'list'>
8章 エラーと例外
出題数 4/ 40問(10%)
8.1 構文エラーと例外
- エラーの種類
- 構文エラー
- 構文の誤りにより発生したエラー
- SyntaxError
- IndentationError
- 構文の誤りにより発生したエラー
- 例外
- 構文エラー以外のエラー(構文は正しいがプログラムの実行中に検知)
- ZeroDivisionError
- NameError
- TypeError
- ValueError
- UnicodeError
- UnicodeDecodeError
- IndexError
- 構文エラー以外のエラー(構文は正しいがプログラムの実行中に検知)
- 構文エラー
8.2 例外処理
-
try
文を使用
>>> a + 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> try:
... a + 2
... except NameError:
... print("NameErrorです")
... except:
... print("何かのエラーが起きています")
...
NameErrorです
8.3 例外の強制発生
-
raise
文を使用
>>> raise NameError("変数名が定義されていません")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: 変数名が定義されていません
>>> try:
... raise NameError("変数名が定義されていません")
... except NameError as e:
... print(e)
...
変数名が定義されていません
- 例外発生時の引数を変数として受け取る
>>> try:
... raise Exception('例外発生1', '例外発生2')
... except Exception as e:
... x, y = e.args
... print(x)
... print(y)
...
例外発生1
例外発生2
8.4 クリーンアップ動作
- エラーでもエラーでなくても最後に必ず実行される処理
-
try
~finally
文を使用 - もしくは
with
文により、オブジェクト(ファイルなど)を使用後すぐに適切な方法でのクリーンアップ動作を保証した形で利用できる
>>> try:
... raise NameError
... finally:
... print("終了")
...
終了
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
NameError
>>> try:
... print("try内の実行")
... finally:
... print("終了")
...
try内の実行
終了
8.5 例外処理における役割分担
-
try
- 例外が発生しそうな処理
-
try
節の実行中にエラーが発生した場合、try
節中の残りのコードは実行されず、except
節が処理される
-
except
- 例外発生時に実行する処理
- 後ろの例外を省略するとワイルドカードになる
-
except
節で定義していない例外が発生した場合、finally
節の処理が実行された後に例外が出力(finally
節の先行処理)
-
else
- 例外が発生しなかった場合の処理
-
finally
- 常に実行
>>> def divide(x, y):
... try:
... result = x / y
... print("tryの実行")
... except ZeroDivisionError:
... print("0で割ることはできません")
... else:
... print("計算結果", result)
... finally:
... print("計算終了")
...
>>> divide(3, 0)
0で割ることはできません
計算終了
>>> divide(3, 2)
tryの実行
計算結果 1.5
計算終了
>>> divide(3, '2')
計算終了
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'int' and 'str'
9章 クラス
出題数 2/ 40問(5%)
9.1 クラス、インスタンス、オブジェクト、メソッド
-
クラス
- オブジェクトの設計図のこと(実体を表現するための雛形)
-
def __init__(self)
:関数によりインスタンスを生成する際の処理を定義
-
インスタンス
- クラスを使って生成したオブジェクト
-
オブジェクト
- クラスやインスタンスの総称
- 型がある
- オブジェクトの属性は
オブジェクト名.属性名
で参照(属性参照)
-
メソッド
- クラスに定義された関数(
def メソッド名(self):
) - インスタンスからはメソッドとして呼び出される
インスタンスオブジェクト.メソッド名(関数の引数)
- クラスからは関数として呼び出される
クラスオブジェクト.関数名(インスタンスオブジェクト, 関数の引数)
- クラスに定義された関数(
>>> class Person:
... def __init__(self, name, age):
... self.name = name
... self.age = age
... def say_hello(self, name):
... print("Hello, {}. I am {}.".format(name, self.name))
...
>>> male1 = Person("Tarou", 20)
>>> male2 = Person("Satoshi", 25)
>>> print(male1.name)
Tarou
>>> print(male2.name, male2.age)
Satoshi 25
>>> male1.say_hello("Hanako")
Hello, Hanako. I am Tarou.
>>> class Sample:
... def __init__(self, name):
... self.name = name
... print(name)
...
>>> x = "abc"
>>> s = Sample()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Sample.__init__() missing 1 required positional argument: 'name'
>>> s = Sample(x)
abc
>>> s.__init__(x)
abc
>>> Sample.__init__(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Sample.__init__() missing 1 required positional argument: 'name'
>>> Sample.__init__(s, x)
abc
>>> class Sample2:
... def aaa(self, name):
... self.name = name
... print(name)
...
>>> s = Sample2()
>>> x = "abc"
>>> s.aaa(x)
abc
>>> Sample2.aaa(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Sample2.aaa() missing 1 required positional argument: 'name'
>>> Sample2.aaa(s, x)
abc
9.2 インスタンス変数とクラス変数
-
インスタンス変数
- インスタンスごとに独自の値を持たせることができる
- 定義・参照
- 定義:
self.変数名
- クラス直下から参照:
self.変数名
- 関数から参照:
self.変数名
- クラス外から参照:
インスタンス名.変数名
- 定義:
-
クラス変数
- クラスの中で変数を定義すると、どのインスタンスにも共通する値を持たせることができる
- 定義・参照
- クラスの中で定義:
変数名
- クラス直下から参照:
変数名
- 関数から参照:
self.変数名
- クラス外から参照:
クラスオブジェクト.変数名
またはインスタンス名.変数名
- クラスの中で定義:
>>> class Sample:
... list_a = []
... def add_list_a(self, data):
... self.list_a.append(data)
...
>>> sample1 = Sample()
>>> sample1.add_list_a("データ1")
>>> sample2 = Sample()
>>> sample2.add_list_a("データ2")
>>> Sample.list_a
['データ1', 'データ2']
>>> sample1.list_a
['データ1', 'データ2']
>>> sample2.list_a
['データ1', 'データ2']
9.3 継承
- クラスの持つデータ属性やメソッドを引き継ぐ
- 親クラスと同じメソッド名を子クラスで定義すると、親クラスのメソッドを上書きできる
-
super()
は親クラスを指す - 多重継承:複数のクラスを継承(例:クラスAから作成されたB、Cを継承するDを作成)
>>> class Person:
... def __init__(self, name, age):
... self.name = name
... self.age = age
...
>>> class Employee(Person):
... def __init__(self, id):
... self.id = id
...
>>> tarou.name = "Tarou"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'tarou' is not defined
>>> tarou = Employee("0012")
>>> tarou.name = "Tarou"
>>> tarou.age = 20
>>> print(tarou.name, tarou.age, tarou.id)
Tarou 20 0012
>>> tarou = Employee("0012")
>>> print(tarou.name, tarou.age, tarou.id)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Employee' object has no attribute 'name'
>>> class Person:
... def __init__(self, name, age):
... self.name = name
... self.age = age
...
>>> class Employee(Person):
... def __init__(self, name, age, id):
... super().__init__(name, age)
... self.id = id
...
>>> tarou = Employee("Tarou", 20, "0012")
>>> print(tarou.name, tarou.age, tarou.id)
Tarou 20 0012
9.4 プライベートメソッド・プライベート変数
- クラス内からのみ呼び出せる(クラス外からは参照できない)
- メソッド名・変数名の先頭にアンダースコア(_)を2つ付ける
- どうしても呼び出したい場合は、
インスタンス名._クラス名__関数名()
、インスタンス名._クラス名__変数名
で呼び出す
>>> class Employee:
... def __init__(self, name):
... self.__name = name
...
>>> e = Employee('Yamada')
>>> e.name
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Employee' object has no attribute 'name'
>>> e._Employee__name
'Yamada'
9.5 イテレータ・ジェネレータ
-
イテレータ
- クラスを使用してイテレータを実装できる
-
__iter__
メソッド、__next__
メソッドを使用
-
ジェネレータ
- 繰り返し処理を書くときに使用
-
yield
式を使用 - ジェネレータが返すオブジェクトの型はgeneratorクラス型
- ジェネレータ関数作成時には要素数は確定しておらず、他から要素を与えられて初めて確定する
- リスト内包表記での記述も可能
>>> def word(data):
... for s in data:
... yield s
...
>>> for one_word in word("sports"):
... print(one_word)
...
s
p
o
r
t
s
>>> type(word)
<class 'function'>
>>> f = word("sports")
>>> type(f)
<class 'generator'>
エンジニアファーストの会社 株式会社CRE-COエンジニアリングサービス