Variable (变量)
Python 变量是 名字绑定(name binding),不是存储空间。
也就是说:“变量”不是装值的盒子,而是给某个对象取一个名字。
例如:
x = 10
并不是把 10 放入 x,而是:
x -> 指向对象 10
所有变量本质上都是 指向对象的引用。
- 强类型(Strong Type):不会自动将类型转换(比如”1”+2 直接报错)
- 动态类型(Dynamic Type):变量类型在运行时决定,可以随时改变绑定对象
例:
x = 123
x = "abc"
每个变量都有:
| 属性 | 说明 |
|---|---|
| id | 对象的内存地址 |
| type | 对象的类型 |
| value | 对象的值 |
例如:
x = "hello"
print(id(x), type(x), x)
左边是名称,右边是对象:
a = b = 100
表示:
a ----->(100)
b ----->/
Python 使用引用计数决定是否回收对象:
x = []
y = x
引用计数 +1
| 级别 | 说明 |
|---|---|
| L | Local(函数内) |
| E | Enclosing(外层函数) |
| G | Global(模块) |
| B | Built-in(内置) |
例:
x = 1 # global
def outer():
x = 2 # enclosing
def inner():
x = 3 # local
global:修改全局变量
x = 10
def foo():
global x
x = 20
nonlocal:修改外层函数的变量
def outer():
x = 10
def inner():
nonlocal x
x = 20
| 类型 | 示例 |
|---|---|
| 数字 | int, float, complex |
| 字符串 | str |
| 布尔值 | bool |
| 容器类型 | list, dict, tuple, set, frozenset |
| 文件 | io.TextIOWrapper |
| 自定义对象 | class instance |
| 特殊对象 | None |
❄️ 不可变对象(重新绑定)
- int
- float
- bool
- str
- tuple
- frozenset
例:
x = "a"
x = "b" # 实际上是绑定新的对象,不是修改
🔥 可变对象(原地修改)
- list
- dict
- set
- 自定义对象属性
例:
lst = [1,2,3]
lst.append(4) # 修改对象本身
a = [1,2,3]
b = a
b.append(4)
print(a) # [1,2,3,4]
# id 相同
id(a) # 4367042880
id(b) # 4367042880
因为两个变量指向同一个对象。
解决:
# 浅拷贝
b = a.copy()
# 浅拷贝
from copy import copy
b = copy(a)
# 深拷贝
from copy import deepcopy
b = deepcopy(a)
# id 不同
id(a) # 4367042880
id(b) # 4370318400
❌ 错误:
def add_item(item, lst=[]):
lst.append(item)
return lst
✅ 正确:
def add_item(item, lst=None):
if lst is None:
lst = []
lst.append(item)
return lst
a, b = 1, 2
x, *y = [1,2,3,4]
字典解包:
data = {"a": 1, "b": 2}
new = {**data, "c": 3}
用于表达式内赋值
if (x := data.get("x")):
print(x)
if (a, b := point()):
...
常量命名全部大写
HOST = "localhost"
VERSION = "1.0"
- 保存上次计算结果
- 表示无用变量 (丢弃不需要的值)
1 + 2
print(_)
# 3
a, _, c = (1, 2, 3)
print(a, c)
# 1 3
Python 没有真正的私有变量,但支持前缀约定:
_x:内部使用__x:类内私有(Name Mangling)
例:
class A:
__secret = 123
转换为:
_A__secret
写法:
age: int = 10
stock_list: list[str] = []
config: dict[str, str] = {}
- 模块级变量:程序运行期间一直存在
- 函数变量:函数结束后销毁
- 闭包变量:存活于函数对象中
- 类/实例变量:对象被 GC 后释放
比如:website, code, date, detail
class Market(Enum):
SH = "sh"
SZ = "sz"
例如:
CACHE = {} # ❌
应改为:
from functools import lru_cache
通常使用:
config.py
这是正确的。
- 变量 = 名字
- 对象 = 值
- 赋值 = 名字绑定对象
- LEGB 作用域
- global / nonlocal
- 可变 vs 不可变
- 默认参数陷阱
- 正确使用类型注解
- 使用常量、枚举
- 使用 dataclass / TypedDict 管理变量结构
- 清晰命名
- 避免共享可变对象
在 Python 中,全部大写的变量名通常表示常量,即不应该被修改的值。虽然 Python 没有真正的常量类型,但约定俗成地使用全大写变量名来表示常量,以提高代码可读性和可维护性。
具体来说,Python 变量命名规范如下:
- 变量名: 推荐使用小写字母和下划线,例如:
my_variable - 常量名: 推荐使用全部大写字母和下划线,例如:
MAX_VALUE - 类名: 推荐使用驼峰命名法,每个单词首字母大写,例如:
MyClass - 函数名: 推荐使用小写字母和下划线,例如:
my_function
示例:
# 变量
my_variable = 10
# 常量
PI = 3.14159
MAX_CONNECTIONS = 100
# 类
class MyClass:
def __init__(self, value):
self.value = value
# 函数
def my_function(x, y):
return x + y
总结: Python 中,全大写变量名是约定俗成的常量,用于表示不应被修改的值,提高代码的可读性和可维护性。同时,也应该遵守其他命名规范,如小写字母和下划线用于变量和函数名,驼峰命名法用于类名。
Python 函数和方法的参数,以及全局变量,推荐使用小写字母加下划线分隔的命名方式(snake_case),例如 my_variable。常量则使用全大写字母加下划线分隔的命名方式(UPPER_SNAKE_CASE),例如 MY_CONSTANT。
- 这是 Python 中最常见的命名风格,适用于函数名、方法名、变量名和参数名。
- 例如:
def calculate_sum(num1, num2):或者user_name = "John"
- 用于表示常量,也就是在程序运行过程中其值不会改变的变量。
- 例如:
MAX_ITERATIONS = 100
- 在 Python 中,驼峰命名法主要用于类名,例如
MyClass或MyClassName。 - 虽然也可以用于函数和变量,但 PEP 8 风格指南推荐使用 snake_case
- 以一个下划线
_开头的变量或方法表示私有变量或方法,不应该直接从外部访问。 - 例如:
_private_variable
- 函数、方法和参数:小写字母加下划线(snake_case)
- 常量:全大写字母加下划线(UPPER_SNAKE_CASE)
- 类:驼峰命名法(CamelCase)
- 私有变量/方法:单下划线前缀