在Python编程中,全局变量和局部变量的作用域是一个重要的概念。本文将详细介绍Python中全局变量的使用,以及如何通过global关键字在函数内部修改全局变量。
一、全局变量和局部变量
1. 基本概念
1 2 3 4 5 6 7 8 9 10 11 12
| global_var = 10
def func(): local_var = 20 print(f"Inside function: global_var = {global_var}") print(f"Inside function: local_var = {local_var}")
func() print(f"Outside function: global_var = {global_var}")
|
2. 作用域规则
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| x = "global"
def outer(): x = "enclosing"
def inner(): x = "local" print(f"Inner: x = {x}")
inner() print(f"Outer: x = {x}")
outer() print(f"Global: x = {x}")
|
二、global关键字
1. 在函数内部修改全局变量
1 2 3 4 5 6 7 8 9 10 11
| counter = 0
def increment(): global counter counter += 1 return counter
print(increment()) print(counter) print(increment()) print(counter)
|
2. global与局部变量的区别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| x = 10
def func_without_global(): x = 20 return x
print(func_without_global()) print(x)
def func_with_global(): global x x = 20 return x
print(func_with_global()) print(x)
|
3. 在同一函数中声明多个全局变量
1 2 3 4 5 6 7 8 9 10
| count = 0 name = "original"
def update(): global count, name count += 1 name = "updated"
update() print(f"count = {count}, name = {name}")
|
三、全局变量的最佳实践
1. 尽量避免使用全局变量
1 2 3 4 5 6 7 8 9 10 11 12 13
| total = 0
def add_to_total(value): global total total += value
def add_to_total_good(value, total=0): return total + value
total = add_to_total_good(10, 0) total = add_to_total_good(20, total)
|
2. 使用类或模块封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Counter: def __init__(self): self._count = 0
def increment(self): self._count += 1
@property def count(self): return self._count
counter = Counter() counter.increment() counter.increment() print(counter.count)
|
3. 使用函数闭包
1 2 3 4 5 6 7 8 9 10 11 12 13
| def create_counter(): count = 0
def increment(): nonlocal count count += 1 return count
return increment
counter = create_counter() print(counter()) print(counter())
|
四、nonlocal关键字
1. 基本用法
nonlocal用于在嵌套函数中修改外层函数的变量:
1 2 3 4 5 6 7 8 9 10 11
| def outer(): x = 10
def inner(): nonlocal x x = 20
inner() print(f"Outer: x = {x}")
outer()
|
2. global vs nonlocal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| x = "global"
def func1(): global x x = "modified global"
def outer(): x = "enclosing"
def inner(): nonlocal x x = "modified enclosing"
inner() print(f"Inside outer: x = {x}")
func1() print(f"Global: x = {x}") outer()
|
五、综合示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
""" 全局变量综合示例 """
class Config: _instance = None _config = {}
def __new__(cls): if cls._instance is None: cls._instance = super().__new__(cls) return cls._instance
def set(self, key, value): self._config[key] = value
def get(self, key, default=None): return self._config.get(key, default)
config1 = Config() config2 = Config()
config1.set("debug", True) print(config2.get("debug")) print(config1 is config2)
def create_logger(): logs = []
def log(message): logs.append(message) return logs
return log
logger = create_logger() logger("Message 1") logger("Message 2") print(logger([]))
class StateMachine: def __init__(self): self._state = "idle" self._transitions = { "idle": {"start": "running"}, "running": {"stop": "idle", "pause": "paused"}, "paused": {"resume": "running", "stop": "idle"} }
def transition(self, action): if action in self._transitions.get(self._state, {}): self._state = self._transitions[self._state][action] return True return False
@property def state(self): return self._state
sm = StateMachine() print(sm.state) sm.transition("start") print(sm.state) sm.transition("pause") print(sm.state)
|
六、注意事项
1. 全局变量的线程安全性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| import threading
counter = 0
def increment_ntimes(n): for _ in range(n): global counter counter += 1
t1 = threading.Thread(target=increment_ntimes, args=(100000,)) t2 = threading.Thread(target=increment_ntimes, args=(100000,))
t1.start() t2.start() t1.join() t2.join()
print(counter)
|
2. 模块级全局变量
3. 调试全局变量问题
1 2 3 4 5 6 7 8 9 10
| x = 10 y = "hello"
def show_globals(): for key, value in globals().items(): if not key.startswith('_'): print(f"{key}: {value}")
show_globals()
|