Python str 1個入りタプルやリストを作る時の罠を踏んだ
まとめ
str 要素 1個入りの tuple, list を作るときは括弧で作ると安全。
t = ('abc',) # ケツカンマがないと怒られる l = ['abc']
tuple() や list() のコンストラクタ形式を使うと罠にはまるかも。
経緯
('abc',) ['abc']
↑の結果が欲しくて↓のようにすると、
t = tuple('abc') l = list('abc')
↓のようになって Why となったわけです。
('a', 'b', 'c') ['a', 'b', 'c']
よくよく考えると、tuple, list のコンストラクタは class tuple([iterable]) , class list([iterable]) で、 Python では str 自体が Iterable なので、
t = tuple('abc') l = list('abc')
とすると、'abc' が Itarable 扱いされて 1 文字ごとになったタプル/リストが作られたと。
('a', 'b', 'c') ['a', 'b', 'c']
str 単体でも str の Iterable でも受け付けるようなメソッド書くとき
def hoge (arg: Union[str. Iterable[str]]) -> None:
後のコードを共通にするため、単体の時は tuple や list でラップして、というのがよくやる手かと思いますが、↓のようにしてしまうと罠を踏み抜くわけですね。
def hoge (arg: Union[str. Iterable[str]]) -> None: if instanceof(arg, str): arg = tuple(arg) for x in arg: # 何かする
こういうラップするときは
if not instanceof(arg, Iterable): arg1 = (arg, )
とするのが安全ぽい