LoginSignup
2
3

More than 5 years have passed since last update.

【python】思わぬ落とし穴~関数内で変数に代入されるされない~

Last updated at Posted at 2019-02-09

背景

あれ?:thinking:
なんか、再帰関数の中で配列の型だと代入されてint型だと代入されずに処理が終わってまう(´・ω・`)

これってなんでだっけ?、、と思ったのがきっかけ。

変数が代入されないとき

個人的な経験上、変数が上手く代入されないときは
1. 関数の内側か外側かのスコープの問題
2. クラスなどで扱ってる中で変数(オブジェクト)が書き換え不可能になってる
3. その他バグ(その処理が行われる前に落ちてるとか)

まぁ今回、ただの再帰関数を1つ書いてて起こった問題なので案の定スコープの問題でした。

みんなが知ってるスコープの話

  • 約束事1. ローカル変数とグローバル変数を同じと思うべからず
>>> def i_to_1():
...   i = 1
... 
>>> i_to_1()
>>> print(i)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined

あれ?関数内でiで変数使って代入もしてるのになんで??
これはもうそういうお約束なのです(´・ω・`)
(※雑になってすいません)

  • 約束事2. グローバル変数はローカル変数に書き変わらないのである
>>> i = 100
>>> i_to_1()
>>> i
100

だけど変数を配列にしてみると?

>>> def ary_to_1():
...   ary[0] = 1
... 
>>> ary_to_1()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in ary_to_1
NameError: name 'ary' is not defined

配列で同じことをしようとすると、少し違う挙動をするみたいですね。
そこで、次が自分が最初に不思議に思ってた挙動です。

>>> ary = [100]
>>> 
>>> ary_to_1()
>>> 
>>> ary
[1]

あら、変わってるではありませんか!?

まとめ

配列だとスコープの問題を回避して関数内で代入をできると言うことが分かった。
なんでかって?...(すいませんどなたかご教示ください:sob:)

また、用語の使い方に不備があったりするかも知れないのでご指摘いただけると幸いです(ぺこ

2
3
5

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
2
3