LoginSignup
4
5

More than 5 years have passed since last update.

Python3の代入周りのメモ

Last updated at Posted at 2016-06-20

関数定義と代入は毎回新しいオブジェクト編

どこかで見かけた気がするような内容のめも。

In[1]
def a():
    print('a')
f = a
f()
def a():
    print('b')
f()
Out[1]
a
a

λにしても同じ。

In[2]
a = lambda: print('a')
f = a
f()
a = lambda: print('b')
f()
Out[2]
a
a

代入でなければ「意図する」動作をする。

In[3]
a = [1]
f = a
print(f)
a.append(1)
print(f)
a = [2]
a.append(2)
print(f)
Out[3]
[1]
[1, 1]
[1, 1]

詳細はコメントのとおり。

グローバルに影響を与えたり与えなかったりする編

関数の中で代入するとどうなるか、試してみよう!

In[4]
l = 1
def a():
    l = 2
a()
l
Out[4]
1

無事、破壊活動に失敗した。
でも、リストを使うと破壊的な活動ができてしまうぞ!やばい!

In[5]
l = [1]
def a():
    l[0] = 2
a()
l[0]
Out[5]
2

どかーん、、、
この破壊活動のポイント(?)は、引数で渡さなくても中身を変えてしまえるというところ。
関数の中で変数を定義してクロージャを使う場合などは、確かにこのような事が起こっている。

デフォルト引数にappendすると大変なことになるよ編

PyCharmが以下のような親切なメッセージを出すので試してみた。

Default argument value is mutable

This inspection detects when a mutable value as list or dictionary is detected in a default value for an argument. Default argument values are evaluated only once at function definition time, which means that modifying the default value of the argument will affect all subsequent calls of the function.

In[6]
def a(x=[]):
    x.append(1)
    return x
a()
a()
a()
Out[6]
[1,1,1]

ファッ!?
同様に、以下のようなこともできる。

In[7]
def a(x=[0]):
    x[0] += 1
    return x[0]
a()
a()
a()
Out[7]
3
4
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5