class Solution:
def isBalanced(self, root: Optional[TreeNode]) -> bool:
balanced = [True]
def node_height(root):
if not root or not balanced[0]:
return 0
left_height = node_height(root.left)
right_height = node_height(root.right)
if abs(left_height - right_height) > 1:
balanced[0] = False
return 0
return 1 + max(left_height, right_height)
node_height(root)
return balanced[0]
Я понимаю, почему приведенный выше код работает, но когда я меняю значение переменной «сбалансированный» на
balanced = True вместо balanced = [True] в строке 3 и
измените баланс[0] на баланс в строках 6, 13 и 19, я получаю ошибку.
class solution:
def func():
a = 5
b = 7
c = True
def nested_func():
return (a + b, c)
return nested_func()
print('sum is:', func())
Поэтому я попробовал приведенный выше код для проверки (возможно, вложенная функция не может получить переменную, имеющую логическое значение), но смог получить результат «сумма: (12, True)». который показывает, что вложенные функции могут получать переменные вне себя.
Может ли кто-нибудь объяснить это?
Вы правильно поняли UnboundLocalError?
Я получаю сообщение «UnboundLocalError: невозможно получить доступ к локальной переменной «сбалансированный», если она не связана со значением», когда я меняю значение сбалансированного на логическое значение.






Для этого вы можете использовать ключевое слово nonlocal :
...
balanced = True
def node_height(root):
nonlocal balanced
...
Когда определение функции или класса вложено (заключено) в определения других функций, его нелокальные области видимости являются локальными областями охватывающих функций.
В вашем случае node_height вложен в isBalanced, поэтому nonlocal balanced сообщит интерпретатору использовать ту же ссылку balanced, что и isBalanced, вместо создания новой ссылки, которая затеняет другую.
Во втором примере nonlocal не требуется, потому что nested_func только читает переменные. Если вы посмотрите на следующее сравнение:
>>> import dis
>>> dis.dis("def f(): return a")
<7 lines omitted>
Disassembly of <code object f at 0x0000026F07FDC510, file "<dis>", line 1>:
1 0 RESUME 0
2 LOAD_GLOBAL 0 (a)
12 RETURN_VALUE
>>> dis.dis("""
... def f():
... a = 7
... return a""")
<7 lines omitted>
Disassembly of <code object f at 0x0000026F07FDE4C0, file "<dis>", line 2>:
2 0 RESUME 0
3 2 LOAD_CONST 1 (7)
4 STORE_FAST 0 (a)
4 6 LOAD_FAST 0 (a)
8 RETURN_VALUE
Вы можете видеть, что первая функция имеет инструкцию LOAD_GLOBAL, тогда как вторая функция использует LOAD_FAST, поскольку она присваивает значение a, сообщая интерпретатору, что это локальная переменная.
Спасибо, но не могли бы вы объяснить, как работает приведенный ниже код без использования ключевого слова nonlocal?
@DHK Я добавил пояснения для обоих случаев
Вложенные функции могут получать доступ к переменным из своих родительских функций. Однако в первом случае вы не только получаете доступ к значению переменной balanced, но и пытаетесь изменить ее.
Всякий раз, когда вы создаете переменную во вложенной функции с тем же именем, что и переменная в родительской функции, вложенная функция использует свою собственную переменную, созданную внутри вложенной функции.
Итак, в этом коде
def node_height(root):
if not root or not balanced:
return 0
left_height = node_height(root.left)
right_height = node_height(root.right)
if abs(left_height - right_height) > 1:
balanced = False # You are creating the variable here,
# but you are trying to access it above in the first if-else statement.
# That is why you are getting the UnboundlocalError
return 0
return 1 + max(left_height, right_height)
Что касается первого подхода со списком, то, как вы знаете, списки изменяемы, поэтому вы можете обновлять их внутри функции, и он будет обновляться во всей области видимости, поэтому он работает.
И в этом примере, Как уже Ответил Эмил и упомянуто мною выше («Вложенные функции могут получать доступ к переменным из своих родительских функций.»), В этом коде вы не обновляете значение, а просто получаете доступ к значению родительской переменной (переменных), поэтому вы не получаете никаких ошибок.
class solution:
def func():
a = 5
b = 7
c = True
def nested_func():
return (a + b, c)
return nested_func()
print('sum is:', func())
@DHK Добро пожаловать, братан
Какая у вас ошибка?