Python 变量

Python 变量

目录

  1. 什么是变量
  2. 变量命名规则
  3. 变量赋值
  4. 数据类型
  5. 类型转换
  6. 变量的作用域
  7. 可变与不可变类型
  8. 最佳实践

什么是变量

变量是存储数据的容器,可以理解为给数据起的"名字"。通过变量名,我们可以访问和操作存储在内存中的数据。

python 复制代码
# 基本示例
name = "Alice"      # 字符串变量
age = 25            # 整数变量
height = 1.75       # 浮点数变量
is_student = True   # 布尔变量

print(name)         # 输出: Alice
print(age)          # 输出: 25

变量的特点

  • 动态类型: Python是动态类型语言,不需要声明变量类型
  • 随时可变: 变量的值可以随时改变
  • 类型可变: 变量可以被重新赋值为不同类型的数据
python 复制代码
# 动态类型示例
x = 10          # x是整数
print(type(x))  # <class 'int'>

x = "Hello"     # x现在是字符串
print(type(x))  # <class 'str'>

x = [1, 2, 3]   # x现在是列表
print(type(x))  # <class 'list'>

变量命名规则

基本规则

  1. 只能包含: 字母(a-z, A-Z)、数字(0-9)、下划线(_)
  2. 不能以数字开头
  3. 区分大小写 : nameName 是不同的变量
  4. 不能使用Python关键字
python 复制代码
# ✓ 合法的变量名
name = "Alice"
user_name = "Bob"
_age = 25
name1 = "Charlie"
PI = 3.14159

# ✗ 非法的变量名
# 1name = "test"      # 不能以数字开头
# user-name = "test"  # 不能包含连字符
# user name = "test"  # 不能包含空格
# class = "test"      # 不能使用关键字

Python关键字

python 复制代码
# 查看Python所有关键字
import keyword
print(keyword.kwlist)

# 常见关键字:
# False, None, True, and, as, assert, async, await, break,
# class, continue, def, del, elif, else, except, finally,
# for, from, global, if, import, in, is, lambda, nonlocal,
# not, or, pass, raise, return, try, while, with, yield

命名约定

1. 小写字母+下划线(snake_case) - 推荐用于变量和函数
python 复制代码
# ✓ 推荐的命名方式
user_name = "Alice"
total_price = 100.50
is_active = True
max_retry_count = 3
2. 大驼峰命名法(PascalCase) - 用于类名
python 复制代码
# 类名使用大驼峰
class UserProfile:
    pass

class BankAccount:
    pass
3. 全大写+下划线 - 用于常量
python 复制代码
# 常量(约定俗成,实际仍可修改)
MAX_SIZE = 100
PI = 3.14159
DEFAULT_TIMEOUT = 30
4. 单下划线前缀 - 表示"内部使用"
python 复制代码
_internal_var = 42  # 暗示这是内部变量,不应直接访问
5. 双下划线前缀 - 名称修饰(用于类)
python 复制代码
class MyClass:
    def __init__(self):
        self.__private = 42  # 名称会被修饰为 _MyClass__private

有意义的命名

python 复制代码
# ✗ 不好的命名
a = 10
b = 20
c = a + b

# ✓ 好的命名
width = 10
height = 20
area = width * height

# ✗ 不清晰的命名
d = {"name": "Alice", "age": 25}

# ✓ 清晰的命名
user_info = {"name": "Alice", "age": 25}

变量赋值

基本赋值

python 复制代码
# 单个变量赋值
x = 10
name = "Alice"

# 多个变量赋相同值
a = b = c = 0
print(a, b, c)  # 输出: 0 0 0

# 多个变量赋不同值(元组解包)
x, y, z = 1, 2, 3
print(x, y, z)  # 输出: 1 2 3

# 交换变量值(不需要临时变量)
a = 10
b = 20
a, b = b, a
print(a, b)  # 输出: 20 10

增量赋值

python 复制代码
x = 10

x += 5   # 等价于 x = x + 5, 结果: 15
x -= 3   # 等价于 x = x - 3, 结果: 12
x *= 2   # 等价于 x = x * 2, 结果: 24
x /= 4   # 等价于 x = x / 4, 结果: 6.0
x //= 2  # 等价于 x = x // 2, 结果: 3.0
x %= 2   # 等价于 x = x % 2, 结果: 1.0
x **= 3  # 等价于 x = x ** 3, 结果: 1.0

链式赋值

python 复制代码
# 链式赋值
a = b = c = 100
print(a, b, c)  # 输出: 100 100 100

# 注意:对于可变对象要小心
list1 = list2 = []
list1.append(1)
print(list2)  # 输出: [1] (因为list1和list2指向同一个列表)

数据类型

Python有多种内置数据类型,变量可以存储任何类型的数据。

1. 数值类型

python 复制代码
# 整数(int)
age = 25
count = -10
big_number = 1000000

# 浮点数(float)
price = 99.99
pi = 3.14159
temperature = -5.5

# 复数(complex)
z = 3 + 4j
print(z.real)   # 3.0
print(z.imag)   # 4.0

# 查看类型
print(type(age))        # <class 'int'>
print(type(price))      # <class 'float'>
print(type(z))          # <class 'complex'>

2. 字符串类型(str)

python 复制代码
# 字符串定义
name = "Alice"
greeting = 'Hello'
multi_line = """这是
多行
字符串"""

# 字符串操作
first_name = "John"
last_name = "Doe"
full_name = first_name + " " + last_name  # 拼接: "John Doe"

repeat = "Ha" * 3  # 重复: "HaHaHa"

# f-string (格式化字符串,推荐)
age = 25
message = f"My name is {name} and I'm {age} years old."
print(message)  # My name is Alice and I'm 25 years old.

3. 布尔类型(bool)

python 复制代码
# 布尔值只有两个: True 和 False
is_active = True
is_deleted = False

# 布尔运算
result1 = True and False   # False
result2 = True or False    # True
result3 = not True         # False

# 比较运算返回布尔值
print(10 > 5)   # True
print(10 == 5)  # False
print(10 != 5)  # True

4. 列表类型(list)

python 复制代码
# 列表:有序、可变的集合
fruits = ["apple", "banana", "orange"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]

# 访问元素
print(fruits[0])     # apple
print(fruits[-1])    # orange (最后一个元素)

# 修改元素
fruits[1] = "grape"
print(fruits)        # ['apple', 'grape', 'orange']

# 添加元素
fruits.append("kiwi")           # 添加到末尾
fruits.insert(0, "mango")       # 插入到指定位置

# 删除元素
fruits.remove("apple")          # 删除指定值
del fruits[0]                   # 删除指定索引
last = fruits.pop()             # 删除并返回最后一个元素

5. 元组类型(tuple)

python 复制代码
# 元组:有序、不可变的集合
coordinates = (10, 20)
colors = ("red", "green", "blue")
single_element = (42,)  # 注意:单元素元组需要逗号

# 访问元素
print(coordinates[0])  # 10

# 元组不可修改
# coordinates[0] = 30  # ❌ TypeError

# 元组解包
x, y = coordinates
print(x, y)  # 10 20

6. 字典类型(dict)

python 复制代码
# 字典:键值对的集合
user = {
    "name": "Alice",
    "age": 25,
    "email": "alice@example.com"
}

# 访问值
print(user["name"])        # Alice
print(user.get("age"))     # 25
print(user.get("phone", "N/A"))  # N/A (键不存在时返回默认值)

# 添加/修改
user["phone"] = "123456"
user["age"] = 26

# 删除
del user["email"]
phone = user.pop("phone")

# 遍历字典
for key, value in user.items():
    print(f"{key}: {value}")

7. 集合类型(set)

python 复制代码
# 集合:无序、不重复的元素集合
fruits = {"apple", "banana", "orange"}
numbers = set([1, 2, 3, 4, 5])

# 添加元素
fruits.add("grape")

# 删除元素
fruits.remove("apple")
fruits.discard("kiwi")  # 如果元素不存在,不会报错

# 集合运算
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

print(set1 & set2)   # 交集: {3, 4}
print(set1 | set2)   # 并集: {1, 2, 3, 4, 5, 6}
print(set1 - set2)   # 差集: {1, 2}
print(set1 ^ set2)   # 对称差集: {1, 2, 5, 6}

8. None类型

python 复制代码
# None表示空值或无值
result = None

# 检查是否为None
if result is None:
    print("结果为空")

# 函数没有返回值时返回None
def say_hello():
    print("Hello")

result = say_hello()
print(result)  # None

类型转换

隐式类型转换

python 复制代码
# Python会自动进行某些类型转换
result = 10 + 3.5    # int + float = float, 结果: 13.5
result = True + 1    # bool + int = int, 结果: 2 (True被视为1)

显式类型转换

python 复制代码
# 转换为整数
print(int(3.7))      # 3 (向下取整)
print(int("10"))     # 10
# print(int("3.5"))  # ❌ ValueError

# 转换为浮点数
print(float(10))     # 10.0
print(float("3.14")) # 3.14

# 转换为字符串
print(str(10))       # "10"
print(str(3.14))     # "3.14"
print(str(True))     # "True"

# 转换为布尔值
print(bool(0))       # False
print(bool(1))       # True
print(bool(""))      # False (空字符串)
print(bool("hello")) # True
print(bool([]))      # False (空列表)
print(bool([1]))     # True

# 转换为列表
print(list("hello"))      # ['h', 'e', 'l', 'l', 'o']
print(list((1, 2, 3)))    # [1, 2, 3]
print(list({1, 2, 3}))    # [1, 2, 3]

# 转换为元组
print(tuple([1, 2, 3]))   # (1, 2, 3)

# 转换为集合
print(set([1, 2, 2, 3]))  # {1, 2, 3} (自动去重)

用户输入的类型转换

python 复制代码
# input() 总是返回字符串
age_str = input("请输入年龄: ")  # 用户输入: 25
print(type(age_str))             # <class 'str'>

# 需要手动转换
age = int(input("请输入年龄: "))
print(type(age))  # <class 'int'>

# 安全的类型转换
try:
    number = float(input("请输入数字: "))
    print(f"你输入的数字是: {number}")
except ValueError:
    print("输入无效,请输入一个数字")

变量的作用域

局部变量(Local)

python 复制代码
def my_function():
    local_var = 10  # 局部变量,只在函数内部可用
    print(local_var)

my_function()  # 输出: 10
# print(local_var)  # ❌ NameError: 在函数外部无法访问

全局变量(Global)

python 复制代码
global_var = 100  # 全局变量

def my_function():
    print(global_var)  # 可以读取全局变量

my_function()  # 输出: 100
print(global_var)  # 输出: 100

在函数中修改全局变量

python 复制代码
count = 0

def increment():
    global count  # 声明使用全局变量
    count += 1

increment()
print(count)  # 输出: 1

嵌套作用域(Enclosing)

python 复制代码
def outer():
    outer_var = "outer"

    def inner():
        inner_var = "inner"
        print(outer_var)  # 可以访问外层函数的变量
        print(inner_var)

    inner()
    # print(inner_var)  # ❌ NameError: 无法访问内层函数的变量

outer()

LEGB规则

Python查找变量的顺序:

  1. Local - 局部作用域(当前函数)
  2. Enclosing - 嵌套作用域(外层函数)
  3. Global - 全局作用域(模块级别)
  4. Built-in - 内置作用域(Python内置函数和异常)
python 复制代码
x = "global"

def outer():
    x = "enclosing"

    def inner():
        x = "local"
        print(x)  # local (优先使用局部变量)

    inner()

outer()
print(x)  # global

可变与不可变类型

不可变类型(Immutable)

以下类型的对象一旦创建就不能修改:

  • 整数(int)
  • 浮点数(float)
  • 字符串(str)
  • 元组(tuple)
  • 布尔值(bool)
  • None
python 复制代码
# 字符串是不可变的
text = "Hello"
# text[0] = "h"  # ❌ TypeError

# "修改"字符串实际上是创建新对象
text = text.lower()
print(text)  # "hello" (新的字符串对象)

# 整数是不可变的
x = 10
print(id(x))  # 查看内存地址
x = x + 1
print(id(x))  # 地址改变了,是新对象

可变类型(Mutable)

以下类型的对象可以原地修改:

  • 列表(list)
  • 字典(dict)
  • 集合(set)
python 复制代码
# 列表是可变的
fruits = ["apple", "banana"]
print(id(fruits))  # 查看内存地址

fruits.append("orange")
print(id(fruits))  # 地址不变,是同一个对象
print(fruits)      # ['apple', 'banana', 'orange']

# 字典是可变的
user = {"name": "Alice"}
print(id(user))

user["age"] = 25
print(id(user))  # 地址不变
print(user)      # {'name': 'Alice', 'age': 25}

可变对象的陷阱

python 复制代码
# 陷阱1:多个变量引用同一个可变对象
list1 = [1, 2, 3]
list2 = list1       # list2和list1指向同一个列表
list2.append(4)
print(list1)        # [1, 2, 3, 4] (list1也被影响了!)

# 解决方案:创建副本
list1 = [1, 2, 3]
list2 = list1.copy()  # 或 list2 = list1[:]
list2.append(4)
print(list1)          # [1, 2, 3] (不受影响)
print(list2)          # [1, 2, 3, 4]

# 陷阱2:默认参数使用可变对象
def add_item(item, items=[]):  # ❌ 危险!
    items.append(item)
    return items

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2] (不是预期的[2]!)

# 正确的做法
def add_item(item, items=None):  # ✓ 安全
    if items is None:
        items = []
    items.append(item)
    return items

print(add_item(1))  # [1]
print(add_item(2))  # [2]

最佳实践

1. 使用有意义的变量名

python 复制代码
# ✗ 不好
a = 100
b = 0.08
c = a * b

# ✓ 好
principal = 100
interest_rate = 0.08
interest = principal * interest_rate

2. 避免使用内置函数名作为变量名

python 复制代码
# ✗ 不好:覆盖了内置函数
list = [1, 2, 3]    # 覆盖了list()函数
dict = {"a": 1}     # 覆盖了dict()函数
str = "hello"       # 覆盖了str()函数
sum = 10            # 覆盖了sum()函数

# ✓ 好:使用其他名称
my_list = [1, 2, 3]
my_dict = {"a": 1}
text = "hello"
total = 10

3. 初始化变量

python 复制代码
# ✓ 在使用前初始化变量
total = 0
for i in range(10):
    total += i

# ✗ 可能导致错误
# print(undefined_var)  # NameError

4. 使用类型提示(Type Hints)

python 复制代码
# Python 3.5+ 支持类型提示(可选,但推荐)
def greet(name: str) -> str:
    return f"Hello, {name}"

age: int = 25
price: float = 99.99
names: list[str] = ["Alice", "Bob"]
user_info: dict[str, int] = {"age": 25, "score": 90}

5. 常量使用大写命名

python 复制代码
# 配置常量
MAX_CONNECTIONS = 100
API_KEY = "your-api-key"
DEFAULT_TIMEOUT = 30

# 数学常量
PI = 3.14159265359
E = 2.71828182846

6. 避免全局变量过多

python 复制代码
# ✗ 不好:过度依赖全局变量
count = 0

def increment():
    global count
    count += 1

# ✓ 好:使用类或函数参数
class Counter:
    def __init__(self):
        self.count = 0

    def increment(self):
        self.count += 1

counter = Counter()
counter.increment()

7. 使用解包简化代码

python 复制代码
# ✗ 传统方式
coordinates = (10, 20, 30)
x = coordinates[0]
y = coordinates[1]
z = coordinates[2]

# ✓ 使用解包
x, y, z = coordinates

# 字典解包
user = {"name": "Alice", "age": 25}
name, age = user.values()

# 使用*收集多余元素
numbers = [1, 2, 3, 4, 5]
first, *middle, last = numbers
print(first)   # 1
print(middle)  # [2, 3, 4]
print(last)    # 5

8. 使用is None而不是== None

python 复制代码
value = None

# ✗ 不推荐
if value == None:
    print("值为空")

# ✓ 推荐
if value is None:
    print("值为空")

实战示例

示例1:用户信息管理系统

python 复制代码
# 使用字典存储用户信息
def create_user(name: str, age: int, email: str) -> dict:
    """创建用户信息字典"""
    return {
        "name": name,
        "age": age,
        "email": email,
        "is_active": True
    }

def update_user_age(user: dict, new_age: int) -> None:
    """更新用户年龄"""
    if new_age > 0:
        user["age"] = new_age
    else:
        raise ValueError("年龄必须为正数")

def display_user(user: dict) -> None:
    """显示用户信息"""
    print(f"姓名: {user['name']}")
    print(f"年龄: {user['age']}")
    print(f"邮箱: {user['email']}")
    print(f"状态: {'激活' if user['is_active'] else '未激活'}")

# 使用示例
user1 = create_user("张三", 25, "zhangsan@example.com")
display_user(user1)

update_user_age(user1, 26)
print("\n更新后:")
display_user(user1)

示例2:购物车系统

python 复制代码
# 使用列表和字典实现简单购物车
class ShoppingCart:
    """购物车类"""

    def __init__(self):
        self.items = []  # 商品列表
        self.total = 0   # 总价

    def add_item(self, name: str, price: float, quantity: int = 1) -> None:
        """添加商品到购物车"""
        if price < 0 or quantity < 0:
            raise ValueError("价格和数量必须为非负数")

        item = {
            "name": name,
            "price": price,
            "quantity": quantity,
            "subtotal": price * quantity
        }
        self.items.append(item)
        self._calculate_total()

    def remove_item(self, index: int) -> None:
        """从购物车移除商品"""
        if 0 <= index < len(self.items):
            removed = self.items.pop(index)
            self._calculate_total()
            print(f"已移除: {removed['name']}")
        else:
            print("无效的商品索引")

    def _calculate_total(self) -> None:
        """计算总价"""
        self.total = sum(item["subtotal"] for item in self.items)

    def display_cart(self) -> None:
        """显示购物车内容"""
        if not self.items:
            print("购物车为空")
            return

        print("=" * 40)
        print("购物车内容:")
        print("=" * 40)
        for i, item in enumerate(self.items, 1):
            print(f"{i}. {item['name']}")
            print(f"   单价: ¥{item['price']:.2f}")
            print(f"   数量: {item['quantity']}")
            print(f"   小计: ¥{item['subtotal']:.2f}")
        print("=" * 40)
        print(f"总计: ¥{self.total:.2f}")
        print("=" * 40)

# 使用示例
cart = ShoppingCart()
cart.add_item("苹果", 5.5, 3)
cart.add_item("香蕉", 3.0, 2)
cart.add_item("牛奶", 12.0)
cart.display_cart()

示例3:成绩统计系统

python 复制代码
# 使用列表和统计功能
def calculate_statistics(scores: list[float]) -> dict:
    """计算成绩统计信息"""
    if not scores:
        return {}

    sorted_scores = sorted(scores)
    n = len(sorted_scores)

    # 计算平均值
    average = sum(scores) / n

    # 计算中位数
    if n % 2 == 0:
        median = (sorted_scores[n//2 - 1] + sorted_scores[n//2]) / 2
    else:
        median = sorted_scores[n//2]

    # 计算最高分和最低分
    highest = max(scores)
    lowest = min(scores)

    # 计算及格率(>=60分)
    passed = sum(1 for score in scores if score >= 60)
    pass_rate = (passed / n) * 100

    return {
        "average": round(average, 2),
        "median": median,
        "highest": highest,
        "lowest": lowest,
        "pass_rate": round(pass_rate, 2),
        "total_students": n
    }

def display_statistics(stats: dict) -> None:
    """显示统计信息"""
    if not stats:
        print("没有数据")
        return

    print("\n" + "=" * 40)
    print("成绩统计报告")
    print("=" * 40)
    print(f"学生总数: {stats['total_students']}")
    print(f"平均分: {stats['average']}")
    print(f"中位数: {stats['median']}")
    print(f"最高分: {stats['highest']}")
    print(f"最低分: {stats['lowest']}")
    print(f"及格率: {stats['pass_rate']}%")
    print("=" * 40)

# 使用示例
scores = [85, 92, 78, 65, 90, 88, 72, 95, 60, 82]
stats = calculate_statistics(scores)
display_statistics(stats)

总结

关键要点

  1. 变量命名:

    • 使用有意义的名称
    • 遵循snake_case命名规范
    • 避免使用Python关键字和内置函数名
  2. 数据类型:

    • 数值: int, float, complex
    • 序列: str, list, tuple
    • 映射: dict
    • 集合: set
    • 布尔: bool
    • 空值: None
  3. 类型转换:

    • 使用int(), float(), str(), bool()等进行显式转换
    • 注意处理可能的ValueError
  4. 作用域:

    • 理解LEGB规则
    • 谨慎使用global关键字
    • 优先使用函数参数传递数据
  5. 可变vs不可变:

    • 不可变: int, float, str, tuple, bool, None
    • 可变: list, dict, set
    • 注意可变对象的引用问题
  6. 最佳实践:

    • 使用类型提示提高代码可读性
    • 避免全局变量
    • 使用解包简化代码
    • 使用is None判断空值

常见错误

  • ❌ 使用未初始化的变量
  • ❌ 用内置函数名作为变量名
  • ❌ 忽略可变对象的引用问题
  • ❌ 在函数中使用global滥用全局变量
  • ❌ 使用== None而不是is None

学习资源


记住: 变量是编程的基础,良好的变量命名和使用习惯能让你的代码更易读、易维护。始终选择清晰、有意义的变量名,并理解不同类型变量的特性和行为。

相关推荐
7年前端辞职转AI4 小时前
Python 数据类型
python·编程语言
冰块的旅行4 小时前
python环境导出
python
曲幽4 小时前
我用fastapi-scaff搭了个项目,两天工期缩到两小时,老板以为我开挂了
python·api·fastapi·web·celery·cli·db·alembic·fastapi-scaff
半点闲4 小时前
入门 SQLAlchemy 教程:从 0 到 1 创建数据库
数据库·python·sqlite·sqlalchemy
好家伙VCC4 小时前
# 发散创新:基于事件驱动架构的实时日志监控系统设计与实现在现代分布式系统中,**事件驱动编程模型**正
java·python·架构
测试19984 小时前
postman接口测试详解
自动化测试·软件测试·python·测试工具·测试用例·接口测试·postman
SuniaWang4 小时前
Java 17实战:Record与密封类的黄金搭档
java·开发语言·python
时光不写代码4 小时前
修复 pytest-asyncio 事件循环冲突:完整解决方案
python·pytest·fastapi
2401_827499994 小时前
python项目实战10-网络机器人03
开发语言·python·php