Python Language 引数として変更可能で不変

開発者がmutabilityを考慮する必要がある主要なユースケースの1つは、引数を関数に渡すときです。これは非常に重要です。これは、スコープに属していないオブジェクトを修正する機能を決定するため、つまり機能に副作用がある場合に機能を決定するためです。これは、関数の結果をどこで利用可能にしなければならないかを理解するためにも重要です。

>>> def list_add3(lin):
    lin += [3]
    return lin

>>> a = [1, 2, 3]
>>> b = list_add3(a)
>>> b
[1, 2, 3, 3]
>>> a
[1, 2, 3, 3]

ここで間違いは、関数のパラメータとしてのlinローカルで変更できると考えることです。代わりに、 linおよび参照同じオブジェクト。 aこのオブジェクトは変更可能であるため、変更はインプレースで行われます。つまり、 lina両方で参照されるオブジェクトが変更されます。 linは実際に返される必要はありません。すでにこのオブジェクトへの参照がaの形でaです。 ab endは同じオブジェクトを参照します。

これはタプルでは同じではありません。

>>> def tuple_add3(tin):
    tin += (3,)
    return tin

>>> a = (1, 2, 3)
>>> b = tuple_add3(a)
>>> b
(1, 2, 3, 3)
>>> a
(1, 2, 3)

関数の開始時にtinおよびリファレンス同じオブジェクト。 aしかし、これは不変のオブジェクトです。関数はそれを修正しようとするときに、 tin一方で、変更を加えた新しいオブジェクトを受け取り、元のオブジェクトへの参照を保持します。 aこの場合、 tin返すことは必須であるか、新しいオブジェクトが失われます。

運動

>>> def yoda(prologue, sentence):
    sentence.reverse()
    prologue += " ".join(sentence)
    return prologue

>>> focused = ["You must", "stay focused"]
>>> saying = "Yoda said: "
>>> yoda_sentence = yoda(saying, focused)

注: reverse動作がインプレースで行われます。

この機能についてどう思いますか?副作用はありますか?リターンは必要ですか?コールの後、何をsayingですか? focused ?関数が同じパラメータで再度呼び出されるとどうなりますか?