python基础语法学习: 动态类型

文章目录

python动态类型

什么是动态类型

动态类型 是指变量的类型在运行时才确定,而不是在编译时确定。变量本身没有固定类型,它只是一个"标签",指向某个对象,对象的类型决定了这个变量能做什么。

与静态类型进行对比

特性 动态类型(Python) 静态类型(C/Java)
类型检查时机 运行时 编译时
变量声明 不需要声明类型 必须声明类型
变量能否改类型 可以 不可以
灵活性 高 低(但更安全)

python中动态类型的表现

python 复制代码
x = 10          # x 指向 int 对象
print(type(x))  # <class 'int'>

x = "hello"     # 同一个变量,现在指向 str 对象
print(type(x))  # <class 'str'>

x = [1, 2, 3]   # 又变成 list
print(type(x))  # <class 'list'>

变量 x 不是"装数据的盒子",而是"贴在对象上的标签"。每次赋值只是让标签贴到新对象上。

可以用id() 验证

objc 复制代码
x = 10
print(id(x))   # 例如 140234...
x = "hello"
print(id(x))   # 地址完全变了,说明指向了新对象

python 中 id() 是一个内置函数, 用于返回对象的唯一标识 (identity) 返回一个整数, 表示该对象在当前生命周期内的唯一标识

is运算符本质上就是比较两个对象的 id

动态类型常见错误

可变默认参数

python 复制代码
def add_item(item, lst=[]):   # 危险!
    lst.append(item)
    return lst

print(add_item(1))   # [1]
print(add_item(2))   # [1, 2]  ← 期望是 [2],但默认参数只创建一次

当 Python 执行到 def add_item(...) 这一行时,它会:

  1. 创建一个空列表 []
  2. 把这个列表对象绑定 为 lst 的默认值
  3. 之后每次调用函数,如果没有传 lst,就复用同一个列表对象

所以并不是"每次进入函数重新创建",而是"定义函数时创建一次,之后一直用这一个"。

类型错误在运行时候才会暴露

python 复制代码
def add(a, b):
    return a + b

print(add(1, 2))        # 3
print(add("a", "b"))    # "ab"
print(add(1, "b"))      # TypeError,运行到这行才报错

隐式类型转换带来的困惑

objc 复制代码
print(1 == True)     # True(bool 是 int 子类)
print(0 == False)    # True
print("1" == 1)      # False(不会自动转换)

动态类型的优缺点

优点

  • 代码简洁,写起来快
  • 灵活,同一个函数可处理多种类型(鸭子类型)
  • 适合快速原型、脚本、数据分析

缺点

  • 类型错误在运行时才暴露,大型项目难维护
  • IDE 提示和重构能力弱
  • 性能略低(每次操作要查类型)

弥补动态类型的不足

类型注解
objc 复制代码
def greet(name: str, age: int) -> str:
    return f"{name} is {age}"


greet("Tom", 20)

注解不影响运行,只是给人和工具看的

鸭子类型(Duck Typing)

"如果它走起来像鸭子,叫起来像鸭子,那它就是鸭子。"

python 复制代码
def process(obj):
    obj.read()   # 不关心类型,只要它有 read 方法

process(open("a.txt"))   # 文件可以
process(io.StringIO())   # 内存流也可以
运行时类型检查
python 复制代码
def add(a, b):
    if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
        raise TypeError("参数必须是数字")
    return a + b

raise:主动触发异常(手动制造报错)

TypeError:类型不对时专用的异常(内置)

  • 别的常见内置异常:ValueError(值不对)、IndexError、KeyError

引号里的字符串:自定义报错提示,会打印在 Traceback 里面

相关推荐
锋行天下10 小时前
langgraph 后端发自定义数据,前端接收方法概括
人工智能·python
benchmark_cc11 小时前
用 QuantDash 读取单只股票五档盘口:抽样、缺失值检查与复现记录
python·数据分析·pandas·量化交易·股票数据·quantdash
曲径海盗12 小时前
【Python 学习第 55 天】列表基础
python·学习笔记·编程入门
专注仿真12 小时前
知识问答模型用到的算法集详解及代码实例
python·算法·代码·大模型训练·控制算法
jyOverQ12 小时前
我写了一个 CSDN Markdown 图片助手:告别本地图片逐张上传
python·工具·csdn
SomeOtherTime13 小时前
Rust所有权(AI回答)
开发语言·后端·rust
Easyhood13 小时前
Android 开发入门实践(十四):Compose 副作用入门与四个常用 API
android·开发语言·kotlin·android jetpack·compose
白杨尚青14 小时前
C++进阶篇(六):map 和 set 的模拟实现——用红黑树封装 mymap/myset(迭代器 + operator[])
开发语言·c++·迭代器·stl·set·map·红黑树
刘马想放假16 小时前
CANviz 使用指南|Linux 安装、DBC 解码、实时曲线与 J1939 实战
linux·python·websocket
2601_9679873716 小时前
python判断变量名不要调用任何函数实现
python·函数·语法·判断·变量名