このトピックに関する他の質問をほぼすべて読みましたが、私のコードはまだ機能しません。
Python 変数のスコープについて何かが欠けていると思います。
これが私のコードです:
PRICE_RANGES = {
64:(25, 0.35),
32:(13, 0.40),
16:(7, 0.45),
8:(4, 0.5)
}
def get_order_total(quantity):
global PRICE_RANGES
_total = 0
_i = PRICE_RANGES.iterkeys()
def recurse(_i):
try:
key = _i.next()
if quantity % key != quantity:
_total += PRICE_RANGES[key][0]
return recurse(_i)
except StopIteration:
return (key, quantity % key)
res = recurse(_i)
そして私は
「グローバル名 '_total' が定義されていません」
問題は割り当てにあることはわかっています_total
が、その理由がわかりません。recurse()
親関数の変数にアクセスできないのでしょうか?
Python 変数スコープについて私が何を見逃しているのか、誰か説明してくれませんか?
ベストアンサー1
Python 3では、nonlocal
声明非ローカル、非グローバルスコープにアクセスします。
このnonlocal
ステートメントにより、変数定義は最も近いスコープ内で以前に作成された変数にバインドされます。次に例をいくつか示します。
def sum_list_items(_list):
total = 0
def do_the_sum(_list):
for i in _list:
total += i
do_the_sum(_list)
return total
sum_list_items([1, 2, 3])
上記の例は、次のエラーで失敗します:UnboundLocalError: local variable 'total' referenced before assignment
を使用するとnonlocal
、コードを動作させることができます:
def sum_list_items(_list):
total = 0
def do_the_sum(_list):
# Define the total variable as non-local, causing it to bind
# to the nearest non-global variable also called total.
nonlocal total
for i in _list:
total += i
do_the_sum(_list)
return total
sum_list_items([1, 2, 3])
しかし、「最も近い」とはどういう意味でしょうか? 別の例を挙げます。
def sum_list_items(_list):
total = 0
def do_the_sum(_list):
# The nonlocal total binds to this variable.
total = 0
def do_core_computations(_list):
# Define the total variable as non-local, causing it to bind
# to the nearest non-global variable also called total.
nonlocal total
for i in _list:
total += i
do_core_computations(_list)
do_the_sum(_list)
return total
sum_list_items([1, 2, 3])
上記の例では、は関数total
内で定義された変数にバインドされdo_the_sum
、sum_list_items
関数で定義された外部変数にはバインドされないため、コードは を返します0
。ただし、次のように二重ネストを行うことは可能です。上記の例でtotal
が宣言されている場合は、期待どおりに動作します。nonlocal
do_the_sum
def sum_list_items(_list):
# The nonlocal total binds to this variable.
total = 0
def do_the_sum(_list):
def do_core_computations(_list):
# Define the total variable as non-local, causing it to bind
# to the nearest non-global variable also called total.
nonlocal total
for i in _list:
total += i
do_core_computations(_list)
do_the_sum(_list)
return total
sum_list_items([1, 2, 3])
上記の例では、非ローカル割り当ては、total
ローカルな変数を見つける前に 2 レベル上まで移動しますsum_list_items
。