2019年11月16日

issubclass() と str.startswith()

ビルトイン関数の issubclass() は、第2引数として type または type の tuple を受け入れます。
>>> issubclass(bool, int)  # 第2引数が type
True

>>> issubclass(bool, (int, float))  # 第2引数が type の tuple
True
複数の型でチェックをしたい時に、issubclass() を複数回呼ぶ必要がないので、単純に便利ですよね。

さらに、この第2引数は、tuple が入れ子になっていても受け入れられます。

>>> issubclass(bool, ((int, bool), float))  # tuple の中に tuple
True

>>> issubclass(bool, (((((int,),),),),))  # 5重の tuple
True



似たようなインターフェースは、str の startswith() にも用いられています。
>>> 'abc'.startswith('a')  # 引数が str
True

>>> 'abc'.startswith(('A', 'a'))  # 引数が str の tuple
True
ここまでは issubclass() と同様です。

ところが、str の startswith() は tuple の入れ子を受け入れません。

>>> 'abc'.startswith((('A', 'a'), 'b'))  # tuple の入れ子はエラー
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'tuple' object to str implicitly
この微妙な違いは、単なる実装の都合と思われます。issubclass() は第2引数が tuple であれば再帰呼び出しをするようになっていて、str の startswith() は再帰呼び出しをしない実装なのでしょう。ちょっとした不統一ですね。
isinstance() と str.endswith() についても同様です。


余談ですが、引数が空の tuple だった場合の動作は共通で、いずれも False が返ります。
>>> issubclass(bool, tuple())
False

>>> 'abc'.startswith(tuple())
False

0 件のコメント:

コメントを投稿