You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Python部分全局变量无需global即可在函数中访问?

Python全局变量访问差异的原因解析

核心原因:变量的"读取"与"赋值"操作的作用域规则

Python对函数内变量的作用域判断逻辑很明确:

  • 如果函数内只读取变量的值,不对变量本身进行赋值,Python会自动向上查找作用域,找到全局变量就直接使用,不需要global声明。
  • 如果函数内存在对变量本身的赋值操作(比如var = ...或var += ...),Python会默认这个变量是局部变量,此时如果在赋值前尝试读取它,就会抛出UnboundLocalError。

针对你的代码的具体分析

为什么dp可以正常访问

dp是列表类型的全局变量,你在函数内的所有操作都没有给dp变量本身重新赋值:

  • print(dp):直接读取全局的dp变量
  • dp[i] == 0:读取dp列表的元素值
  • dp[i] = 1:修改dp列表的元素,只是改变列表内部的内容,不是重新定义dp这个变量

Python会认为你只是在操作全局列表的内容,不是创建局部变量,所以不需要global声明就能正常访问。

为什么curStr会报错

curStr是字符串类型的全局变量,你在函数内存在明确的赋值操作:

  • curStr += cards[i]:等价于curStr = curStr + cards[i],是给curStr变量本身赋值
  • curStr = curStr[:-len(cards[i])]:直接给curStr变量赋值

Python看到这些赋值操作后,会默认curStr是局部变量,但函数开头的print(curStr)在局部的curStr被赋值前就执行了,所以抛出UnboundLocalError——局部变量还没被赋值就被引用。

解决方法

方法1:用global声明全局变量

在函数开头明确声明curStr是全局变量,告诉Python不要把它当成局部变量:

import sys
input = sys.stdin.readline

n = int(input())
k = int(input())

cards = [input().rstrip() for _ in range(n)]

dp = [1] * n
res = set()
curStr = ""

def concat(cards, k, n, count):
    global curStr  # 声明curStr为全局变量
    print(dp)
    print(curStr)

    if count == k:
        res.add(curStr)
        return
    
    for i in range(n):
        if dp[i] == 0:
            curStr += cards[i]
            dp[i] = 1
        
            concat(cards, k, n, count + 1)

            dp[i] = 0
            curStr = curStr[:-len(cards[i])] 


concat(cards, k, n, 0)
print(len(res))

方法2:避免全局变量,改用参数传递

更推荐的写法是把curStr作为递归参数传递,这样不需要依赖全局变量,代码逻辑更清晰:

import sys
input = sys.stdin.readline

n = int(input())
k = int(input())

cards = [input().rstrip() for _ in range(n)]

dp = [1] * n
res = set()

def concat(cards, k, n, count, curStr):
    print(dp)
    print(curStr)

    if count == k:
        res.add(curStr)
        return
    
    for i in range(n):
        if dp[i] == 0:
            new_str = curStr + cards[i]
            dp[i] = 1
        
            concat(cards, k, n, count + 1, new_str)

            dp[i] = 0


concat(cards, k, n, 0, "")
print(len(res))

内容的提问来源于stack exchange,提问作者YSEO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 01:27:44