Python 中的全局变量 global 和 globals()

本文介绍了Python中global关键字和globals()函数的区别与用法。


global用于在函数内部声明要修改的全局变量,而globals()返回包含所有全局变量的字典,可用于动态访问和修改全局变量。


文章通过示例展示了二者的基本用法、嵌套函数中的应用、动态操作全局变量的技巧,并对比了它们的特性和适用场景。


同时强调了避免过度使用全局变量的最佳实践,建议优先使用类和参数传递。


最后提供了检查变量是否存在、获取用户定义变量等高级技巧,帮助开发者合理使用全局变量。


Python 中的 globalglobals()


这两者都与 Python 的全局变量相关,但作用和使用方式不同。


一、global 关键字

作用

在函数内部声明要修改的变量是全局变量,而不是创建局部变量。

基本用法

python

python 复制代码
# 全局变量
x = 10
name = "Alice"

def func1():
    # 只读取全局变量,不需要 global
    print(x)  # 10

def func2():
    # 要修改全局变量,必须用 global
    global x
    x = 20  # 修改全局变量
    print(x)  # 20

def func3():
    # 不用 global,会创建局部变量
    x = 30  # 这是局部变量
    print(x)  # 30

func1()
func2()
func3()
print(x)  # 20(全局变量被修改为 20)

修改多个全局变量

python

python 复制代码
a = 1
b = 2
c = 3

def modify():
    global a, b, c  # 声明多个全局变量
    a = 10
    b = 20
    c = 30

modify()
print(a, b, c)  # 10 20 30

嵌套函数中使用

python

python 复制代码
count = 0

def outer():
    count = 100  # 局部变量
    
    def inner():
        global count  # 这指向最外层的全局变量,不是 outer 的 count
        count = 200
    
    inner()
    print("outer 中的 count:", count)  # 100(未被修改)
    print("全局 count:", globals()['count'])  # 200

outer()

二、globals() 函数

作用

返回当前全局符号表的字典,包含所有全局变量。

基本用法

python

python 复制代码
# 查看所有全局变量
print(globals())
# 输出类似:
# {'__name__': '__main__', '__doc__': None, ...}

# 访问全局变量
x = 100
name = "Python"

print(globals()['x'])     # 100
print(globals()['name'])  # Python

# 修改全局变量
globals()['x'] = 200
print(x)  # 200

# 添加新的全局变量
globals()['new_var'] = "Hello"
print(new_var)  # Hello

动态操作全局变量

python

python 复制代码
# 动态创建全局变量
var_names = ['a', 'b', 'c']
for i, name in enumerate(var_names):
    globals()[name] = i + 1

print(a, b, c)  # 1 2 3

# 动态修改变量
var_name = input("输入要修改的变量名: ")
new_value = input("输入新值: ")
if var_name in globals():
    globals()[var_name] = new_value

三、global vs globals()

对比表格

特性 global globals()
类型 关键字 函数
用途 声明要修改的全局变量 获取/修改全局变量字典
修改方式 直接赋值 字典操作
需要声明 需要先声明 不需要声明
代码可读性 更清晰 较隐晦

实际对比

python

python 复制代码
# 方式1:使用 global
counter = 0

def increment():
    global counter
    counter += 1

# 方式2:使用 globals()
def increment2():
    globals()['counter'] += 1

increment()
increment2()
print(counter)  # 2

四、常见应用场景

1. 配置管理

python

python 复制代码
# config.py 风格
DEBUG = True
VERSION = "1.0"

def set_debug(status):
    global DEBUG
    DEBUG = status

def set_version(version):
    globals()['VERSION'] = version  # 也可以用 globals()

2. 计数器

python

python 复制代码
call_count = 0

def track_calls():
    global call_count
    call_count += 1
    print(f"函数被调用了 {call_count} 次")

3. 动态导入

python

python 复制代码
# 动态创建模块级别的变量
module_name = "math"
globals()[module_name] = __import__(module_name)

print(math.sqrt(16))  # 4.0

五、注意事项和最佳实践

⚠️ 避免过度使用全局变量

python

python 复制代码
# ❌ 不好的做法:过度依赖全局变量
total = 0
def add(x):
    global total
    total += x

def subtract(x):
    global total
    total -= x

# ✅ 更好的做法:使用类和参数
class Calculator:
    def __init__(self):
        self.total = 0
    
    def add(self, x):
        self.total += x
    
    def subtract(self, x):
        self.total -= x

⚠️ 函数内的变量优先级

python

python 复制代码
x = 10

def test():
    x = 20          # 局部变量
    print(x)        # 20
    print(globals()['x'])  # 10

test()

⚠️ 可变对象不需要 global

python

python 复制代码
# 列表、字典等可变对象
my_list = [1, 2, 3]

def modify():
    # 修改列表内容不需要 global
    my_list.append(4)    # ✅ 可以
    my_list[0] = 10      # ✅ 可以
    
    # 但是重新赋值需要 global
    # my_list = [4, 5, 6]  # ❌ 这会创建局部变量

modify()
print(my_list)  # [10, 2, 3, 4]

六、高级技巧

检查变量是否存在

python

python 复制代码
if 'my_var' in globals():
    print(f"my_var = {my_var}")
else:
    print("my_var 不存在")

获取所有用户定义的全局变量

python

python 复制代码
def get_user_globals():
    return {k: v for k, v in globals().items() 
            if not k.startswith('__')}

x = 1
y = 2
print(get_user_globals())  # {'x': 1, 'y': 2}

临时修改全局变量

python

python 复制代码
DEBUG = True

def temp_disable_debug():
    old_debug = globals()['DEBUG']
    globals()['DEBUG'] = False
    # 执行某些操作...
    globals()['DEBUG'] = old_debug

总结

  • global:声明要修改的全局变量,代码清晰,推荐使用

  • globals():返回全局变量字典,适合动态操作

  • 最佳实践:尽量少用全局变量,考虑使用类、函数参数传递

  • 注意 :修改可变对象(列表、字典)的内容不需要 global

相关推荐
万笑佛8 分钟前
Python 实现Kafka SASL认证生产消费
python
m0_617493942 小时前
Python OpenCV 透视变换(Perspective Transform)详解与实战
开发语言·python·opencv
小李不困还能学2 小时前
PyCharm下载安装与配置教程
ide·python·pycharm
博观而约取厚积而薄发2 小时前
Pytest 从入门到精通,一篇就够(超详细实战教程)
python·测试工具·单元测试·自动化·pytest
imzed2 小时前
使用 Playwright + Pytest 构建 Web UI 自动化测试框架
python·自动化·pytest
普通网友2 小时前
pytest一些常见的插件
开发语言·python·pytest
时空系2 小时前
Python 高性能高压缩打包器 —— 基于 JianPy 语义分析引擎
python
cndes3 小时前
给Miniconda换源,让包下载更迅速
开发语言·python
Metaphor6923 小时前
使用 Python 添加、隐藏和删除 PDF 图层
python·pdf·图层