他のユーザーが指摘しているように、Python のコア型は設計上不変です。
>>> int.frobnicate = lambda self: whatever()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'int'
Python のユーザー定義型はデフォルトで変更可能であるため、サブクラスを作成することで、説明した効果を確実に実現できます。
>>> class MyInt(int):
... def frobnicate(self):
... print 'frobnicating %r' % self
...
>>> five = MyInt(5)
>>> five.frobnicate()
frobnicating 5
>>> five + 8
13
MyInt
サブクラスを公開する必要もありません。インスタンスを構築する関数またはメソッドでインラインで直接定義することもできます。
確かに、イディオムに堪能な Python プログラマーが、この種のサブクラス化を正しいことと見なす状況がいくつかあります。たとえば、例で参照している読みやすさの問題に正確に対処するために、名前付きメンバーを追加os.stat()
するサブクラスを返します。tuple
>>> import os
>>> st = os.stat('.')
>>> st
(16877, 34996226, 65024L, 69, 1000, 1000, 4096, 1223697425, 1223699268, 1223699268)
>>> st[6]
4096
>>> st.st_size
4096
とはいえ、あなたが与えた特定の例ではfloat
、item.price
(または他の場所で)サブクラス化することがPythonicのことと見なされる可能性は非常に高いとは思いません。それが主なユースケースである場合、誰かがメソッドを追加することを決定することを容易に想像できます。より一般的なものを探している場合は、次のように、意図した意味をより明確にするために名前付き引数を使用する方が理にかなっているかもしれません。price_should_equal()
item
should_equal(observed=item.price, expected=19.99)
またはそれらの線に沿った何か。少し冗長ですが、改善できることは間違いありません。Ruby スタイルのモンキー パッチに対するこのようなアプローチの考えられる利点は、orshould_equal()
だけでなく、任意の型に対して簡単に比較を実行できることです。しかし、あなたがたまたま提供してくれた特定の例の詳細にとらわれすぎているのかもしれません。int
float