📘
学習記録_Python実践レシピ(第6章、第4章、第16章)
1. __add__ の動き
-
__add__は + 演算子をオーバーロードするための特殊メソッド。 - 例えば:
class Vector:
def __init__(self, x):
self.x = x
def __add__(self, other):
return Vector(self.x + other.x)
v1 = Vector(10)
v2 = Vector(5)
v3 = v1 + v2 # v1.__add__(v2) が呼ばれる
print(v3.x) # 15
🔹 ポイント
-
+を書いた時に自動的に__add__が呼ばれる。 -
__radd__という「右側オペランド用」のメソッドもある。
2. local x
-
localというキーワードは Pythonには存在しない。 -
変数は「ローカル変数」「グローバル変数」と呼ぶが、それを明示するキーワードはない。
-
代わりに使うのは:
-
global x→ グローバル変数を使う -
nonlocal x→ 外側のスコープの変数を使う
-
3. dataclass
3.1 デコレータ
-
@dataclassは クラスの前に記述して使う。 - 自動的に
__init__,__repr__,__eq__などを生成してくれる。
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
3.2 __repr__
-
dataclassでは__repr__が自動生成される。 - 例:
p = Point(1, 2)
print(p) # Point(x=1, y=2)
p # >>> Point(x=1, y=2)
-
print(p)もpも、内部的にはrepr(p)を呼んでいる。 - 自分で
__repr__を定義すれば、出力をカスタマイズできる。
3.3 asdict / astuple
- dataclass のインスタンスを 辞書型やタプル型に変換できる。
from dataclasses import asdict, astuple
print(asdict(p)) # {'x': 1, 'y': 2}
print(astuple(p)) # (1, 2)
4. namedtuple との違い
-
namedtupleも フィールドに名前を付けられるタプル。
from collections import namedtuple
P = namedtuple("Person", ["name", "age"])
p = P("Alice", 30)
print(p.name) # Alice
print(p.age) # 30
違い
-
dataclass: ミュータブル(値を変更できる) -
namedtuple: イミュータブル(変更不可)
5. id() と整数の挙動
li = 1
print(id(li)) # A
li += 2
print(id(li)) # B
-
id()は オブジェクトの実体のアドレスを返す。 - 整数は イミュータブル なので、
+=は「新しいオブジェクトを作成」する。 - したがって
id()の結果は変わる。
6. help() と __help__
-
help(obj)→ 組み込みのヘルプシステム(pydoc)が呼ばれる。 -
__help__→ そのような特殊メソッドは存在しない。
7. 関数定義の引数名に注意
def func(type):
print(type)
-
typeは 組み込み関数type()を上書きしてしまうのでよくない。 - 混乱を避けるため、
arg_typeなど別の名前を使うべき。
8. 文字列リテラルの結合
(
'a'
'b'
'c'
)
# → 'abc'
- 改行やカンマがなければ 自動的に結合される。
"""a
b
c"""
# → 改行やスペースを含んだ文字列
9. str.replace
text = 'Hello world'
print(text.replace('l', 'L')) # HeLLo worLd
print(text.replace('l', 'L', 1)) # HeLlo world
- 第3引数は「最大置換回数」。
10. strip
text = 'あああ/いいい/あああ/ううう'
print(text.strip('あ/'))
# → 'いいい/あああ/ううう'
-
stripは「先頭と末尾」からのみ削除する。 - 中間の文字列は削除されない。
- 文字ごとに削除を試し、最初に対象がなければ停止。
11. removeprefix / removesuffix
text = "HelloWorld"
print(text.removeprefix("He")) # "lloWorld"
print(text.removesuffix("World")) # "Hello"
- 先頭または末尾が完全一致した場合のみ削除。
- 部分一致やデフォルトで5文字などは存在しない。
12. f-string の :f
x = 3.14159
print(f"{x:f}") # 3.141590
- デフォルトで 小数点以下6桁。
-
:.2fと書けば小数点以下2桁に丸められる。
13. 正規表現のポイント
13.1 \w
-
\wは「単語構成文字」 - Unicode対応なので
'あ'もマッチする。
13.2 [a-n]+
regex = re.compile('[a-n]+')
regex.fullmatch('eggs') # None
-
's'が範囲外なのでマッチしない。
13.3 名前付きグループ
re.match(r'(?P<last>\w+)', '鈴木')
# last = '鈴木'
13.4 . のエスケープ
-
.→ 任意の1文字 -
\.→ ドットそのもの
13.5 ?
- 直前の要素が 0回か1回。
re.match(r'(\w+) ?(\w+)? (\w+)', 'Guido van Rossum').groups()
# ('Guido', 'van', 'Rossum')
- 最初の
?→ 空白があるかどうか - 2つ目の
?→ middle name があるかどうか
13.6 expand の \1\2
m = re.match(r'(?P<first>\w+) (?P<last>\w+)', '太郎 山田')
print(m.expand(r'名前: \1\2')) # 名前: 太郎山田
-
\1,\2は「グループ番号」の参照。
14. unicodedata.normalize
-
正規化形式:
- NFC: 合成
- NFD: 分解
- NFKC: 互換合成
- NFKD: 互換分解
import unicodedata
unicodedata.normalize("NFKC", "ガ")
15. UTF-8 のエンコード
nf = unicodedata.normalize('NFKC', 'ガ')
print(nf.encode('utf-8'))
# b'\xe3\x82\xac'
-
encode('utf-8')は 文字をバイト列に変換する。 - Python3 の文字列は内部的には Unicode。
- 明示しなければ
str.encode()はデフォルトで'utf-8'を使う。
16. doctest
python -m doctest -v sample_doctest.py
-
-v→ verbose(詳細モード)で実行。 -
doctest.testfile("sample.txt")→ 外部ファイルに書かれた doctest を実行できる。
17. CIサーバー
- **Continuous Integration(継続的インテグレーション)**の略。
- コードが変更されるたびに自動でテストやビルドを実行する仕組み。
- 例: GitHub Actions, Jenkins, CircleCI など。
18. MagicMock でメソッド差し替え
a = test()
a.comon = MagicMock()
- これは「インスタンス変数
comonを MagicMockオブジェクトに上書き」している。 - その後
a.comon()と呼ぶと、差し替えたMagicMockが呼ばれる。 - つまり「メソッドの実行」ではなく「メソッドの定義そのものを差し替え」ている。
✅ まとめ
-
__add__→+演算子のオーバーロード - dataclass → 自動で
__init__,__repr__などを生成。asdictで辞書化も可能 - namedtuple との違い → イミュータブルかどうか
-
id()→ イミュータブル型は再代入で新しいオブジェクトになる - 正規表現 →
?, 名前付きグループ,\1などは試験に出やすい - UTF-8 → 文字列をバイト列に変換する仕組み
- doctest, CI → 実務寄りの試験対策
- MagicMock → メソッド差し替え
Discussion