ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

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

python基础语法学习: 动态类型 文章目录python动态类型什么是动态类型与静态类型进行对比python中动态类型的表现动态类型常见错误可变默认参数类型错误在运行时候才会暴露隐式类型转换带来的困惑动态类型的优缺点弥补动态类型的不足类型注解鸭子类型Duck Typing运行时类型检查python动态类型什么是动态类型动态类型是指变量的类型在运行时才确定而不是在编译时确定。变量本身没有固定类型它只是一个标签指向某个对象对象的类型决定了这个变量能做什么。与静态类型进行对比特性动态类型Python静态类型C/Java类型检查时机运行时编译时变量声明不需要声明类型必须声明类型变量能否改类型可以不可以灵活性高低但更安全python中动态类型的表现x10# x 指向 int 对象print(type(x))# class intxhello# 同一个变量现在指向 str 对象print(type(x))# class strx[1,2,3]# 又变成 listprint(type(x))# class list变量x不是装数据的盒子而是贴在对象上的标签。每次赋值只是让标签贴到新对象上。可以用id()验证x10print(id(x))# 例如140234...xhelloprint(id(x))# 地址完全变了说明指向了新对象python 中id()是一个内置函数, 用于返回对象的唯一标识 (identity) 返回一个整数, 表示该对象在当前生命周期内的唯一标识is运算符本质上就是比较两个对象的 id动态类型常见错误可变默认参数defadd_item(item,lst[]):# 危险lst.append(item)returnlstprint(add_item(1))# [1]print(add_item(2))# [1, 2] ← 期望是 [2]但默认参数只创建一次当 Python 执行到def add_item(...)这一行时它会创建一个空列表[]把这个列表对象绑定为lst的默认值之后每次调用函数如果没有传lst就复用同一个列表对象所以并不是每次进入函数重新创建而是定义函数时创建一次之后一直用这一个。类型错误在运行时候才会暴露defadd(a,b):returnabprint(add(1,2))# 3print(add(a,b))# abprint(add(1,b))# TypeError运行到这行才报错隐式类型转换带来的困惑print(1True)# Truebool 是int子类print(0False)# Trueprint(11)# False不会自动转换动态类型的优缺点优点代码简洁写起来快灵活同一个函数可处理多种类型鸭子类型适合快速原型、脚本、数据分析缺点类型错误在运行时才暴露大型项目难维护IDE 提示和重构能力弱性能略低每次操作要查类型弥补动态类型的不足类型注解defgreet(name:str,age:int)-str:returnf{name} is {age}greet(Tom,20)注解不影响运行只是给人和工具看的鸭子类型Duck Typing“如果它走起来像鸭子叫起来像鸭子那它就是鸭子。”defprocess(obj):obj.read()# 不关心类型只要它有 read 方法process(open(a.txt))# 文件可以process(io.StringIO())# 内存流也可以运行时类型检查defadd(a,b):ifnotisinstance(a,(int,float))ornotisinstance(b,(int,float)):raiseTypeError(参数必须是数字)returnabraise主动触发异常手动制造报错TypeError类型不对时专用的异常内置别的常见内置异常ValueError(值不对)、IndexError、KeyError引号里的字符串自定义报错提示会打印在 Traceback 里面
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进