アルパカログ

プログラミングとマネジメントがメインです。時々エモいのも書きます。

RubyとPythonで仮引数のデフォルト値がオブジェクトのとき挙動が違う

仮引数のデフォルト値は、Rubyではメソッドが呼ばれたときに作られ、Pythonではメソッドが定義されたときに作られているように見える。

業務ではRubyを書いていて、プライベートでPythonを書いていてハマったのでメモ。最後の hoge2.foo に注目してみてください。

Ruby

[1] pry(main)> class Hoge
[1] pry(main)*   attr_accessor :foo
[1] pry(main)*   
[1] pry(main)*   def initialize(foo: [])
[1] pry(main)*     self.foo = foo
[1] pry(main)*   end  
[1] pry(main)* end  
[2] pry(main)> 
[3] pry(main)> hoge1 = Hoge.new
[4] pry(main)> hoge2 = Hoge.new
[7] pry(main)> 
[8] pry(main)> hoge1.foo.push(1)
=> [1]
[9] pry(main)> hoge1.foo
=> [1]
[10] pry(main)> hoge2.foo
=> []

Python

>>> class Hoge:
...     def __init__(self, foo=[]):
...             self.foo = foo
... 
>>> hoge1 = Hoge()
>>> hoge2 = Hoge()
>>> 
>>> hoge1.foo.append(1)
>>> hoge1.foo
[1]
>>> hoge2.foo
[1]