为何将回文判断逻辑放入函数后触发UnboundLocalError?
回文判断函数封装引发的UnboundLocalError解析
问题描述
编程新手将回文判断逻辑封装到函数中时触发错误:UnboundLocalError: local variable 'czy_to_palindrome' referenced before assignment,但不使用函数时代码可正常运行。以下是报错代码与正常代码的对比:
报错代码
while True: print("Podaj liczbe: ", end="") number = input() czy_to_palindrome = True def palindrome_check(number): for i in range(len(number)): if number[i] != number[len(number)- i - 1]: print("No, ", number, "is NOT a palindrome.") czy_to_palindrome = False break if czy_to_palindrome: print("Yes, ",number, "is a palindrome.") palindrome_check(number)
正常代码
while True: print("Podaj liczbe: ", end="") number = input() czy_to_palindrome = True # def palindrome_check(number): for i in range(len(number)): if number[i] != number[len(number)- i - 1]: print("No, ", number, "is NOT a palindrome.") czy_to_palindrome = False break if czy_to_palindrome: print("Yes, ",number, "is a palindrome.") # palindrome_check(number)
核心原因:变量作用域差异
- 无函数时:
czy_to_palindrome属于循环体的局部变量,整个代码块内可直接读取和修改,不存在作用域冲突。 - 封装函数后:Python的作用域规则是:如果函数内部对某个变量执行赋值操作,会默认将该变量视为函数的局部变量,不再去外层作用域查找同名变量。
在报错代码中,函数palindrome_check里只有在检测到非回文时才会给czy_to_palindrome赋值;如果输入的是回文数,循环不会触发赋值,此时执行if czy_to_palindrome:时,函数会寻找未定义的局部变量,直接抛出错误。外层的czy_to_palindrome = True因为函数内部有赋值操作,不会被函数识别。
修正方案
方案1:将变量改为函数内部局部变量(推荐)
让函数逻辑独立,不依赖外层变量,初始化语句移到函数内部:
while True: print("Podaj liczbe: ", end="") number = input() def palindrome_check(number): czy_to_palindrome = True # 函数内部初始化变量 for i in range(len(number)): if number[i] != number[len(number)- i - 1]: print("No, ", number, "is NOT a palindrome.") czy_to_palindrome = False break if czy_to_palindrome: print("Yes, ",number, "is a palindrome.") palindrome_check(number)
方案2:用nonlocal声明使用外层变量
如果需要复用外层变量,用nonlocal告诉函数该变量来自外层作用域:
while True: print("Podaj liczbe: ", end="") number = input() czy_to_palindrome = True def palindrome_check(number): nonlocal czy_to_palindrome # 声明使用外层作用域的变量 for i in range(len(number)): if number[i] != number[len(number)- i - 1]: print("No, ", number, "is NOT a palindrome.") czy_to_palindrome = False break if czy_to_palindrome: print("Yes, ",number, "is a palindrome.") palindrome_check(number)
内容的提问来源于stack exchange,提问作者Micheal_new
相关产品推荐
相关产品推荐

