华为AI全栈成长计划课程——AI基础篇——第一周笔记2
第2章 Python语言进阶
2.1 函数与模块-函数(def)
函数返回
- 返回语句有多个对象:数字、字符串、列表和字典。
- 返回值是一个tuple。
- 函数为空语句pass时,返回None。
函数对象
- 函数是对象。def是一条可执行语句,创建函数对象,函数名是函数对象的引用。可以赋值给其他变量。
- 函数可以作为函数的参数;函数可以作为容器对象的元素,如List, Dictionary等。
函数参数传递
- 参数的传递是通过把对象赋值给局部的名字。赋值在Python中就意味着引用。函数中的参数与调用者共同引用的同一个对象。
- 在函数内部中给参数赋值不会影响调用者。
- 在函数内部修改可变类型的参数会影响到调用者。
- 不可变类型的参数的行为就像C语言的“by value”方式。如参数是整数,字符串。
- 可变类型的参数的行为就像C语言的“by pointer”方式。如参数是列表。
- 不要使用可变类型作为参数的默认值
全局变量和局部变量
- 对局部变量的赋值不会影响全局变量,特别是在对li赋值的时候,li会指向新的列表对象,原列表对象不变。除非直接调用对象方法,对对象本身的元素作赋值。
- 函数内操作全局变量,声明为global
函数参数匹配的模式
- 位置:位置匹配,从左到右
- 关键字:根据参数名进行匹配
- 可变参数:匹配任意多的参数
- 默认值:提供参数的默认值
函数参数匹配的规则
- 默认参数必须在非默认参数之后
- 在单个函数定义中,只能使用一个tuple参数(*ARG)和一个字典参数(**ARG)
- tuple参数必须在位置参数和默认参数之后
- 字典参数必须在最后定义
思考
- python函数进行与C++一样的重载操作时会覆盖之前定义的函数,而且python无需重载。
lambda匿名函数
- lambda[arg1[, arg2,... argN]]: expression
- lambda 函数可以接收任意多个参数(包括可选参数)并且返回单个表达式的值。lambda 函数不能包含命令,包含的表达式不能超过一个。
- 例:add=lambda x,y:x+y
内部函数
- 内部函数整个函数体都在外部函数的作用域内除了在函数体内,任何地方都不能对其进行调用,除非你将内部函数对象返回给了其他变量(return 内部函数名)
拓展
- 用户定义的函数def,lambda
- 内置函数(C编写,len)
- 内置方法(C编写,dict.get)
- 方法(类中定义的函数)
- 类(
__new__
,__init__
) - 类实例(实现实例方法
__call__
) - 生成器函数
2.2 函数与模块-模块
模块
- 文件名就是模块名+.py,模块名称不能是保留字的名称
- 模块定义了自己独有的命名空间。在其定义的属性,函数,类都隶属于该空间。
- import module1,[module2,[...moduleN]]
- 也可以使用多行导入的方式:
import module1 ...
import moduleN - 推荐的import语句导入模块顺序:python标准库->python第三方库->应用程序自定义模块
- from module import name1,[name2,[...nameN]]。导入一个模块的属性,使用这些属性时就不需要再加入模块名。不推荐使用from module import *,会污染当前命名空间导致覆盖已有名称。
- from module import (name1,name2...nameN)
- import module as ...(换名)
- from module import name as ...
- 搜索模块:主目录、sys.path目录、标准库目录、.pth文件目录。如果系统没有找到模块会抛出找不到该模块的异常。
- globals()和locals():分别返回调用者全局和局部命名空间的字典。
包
- 包是一个有层次的文件目录结构。
- 每个包目录下都必须有一个__init__.py文件,在__init__.py中把包内.py预先导入(from . import module1),才可以执行from package import module成功。
- 文件__init__.py中可以通过__all__(字符串列表)指定from ... import *需要导入的模块。
- 避免导入循环
作用域
- 每个模块就是一个全局作用域。
- 每次调用一个函数就创建一个局部作用域。
- 函数内的赋值对象属局部作用域,除非使用global关键字进行声明。
- 跨模块作用域
2.3 面向对象-类与实例
类与实例
- 与C++的类与实例对象定义基本无异
类定义与实例化
- 实例化一个类和函数调用的语法是一样的。
属性定义
- 类属性与C++的类属性类似。
- 实例属性与C++的成员属性类似,每个对象的实例属性值可能不同。
- 类的所有对象,都可以读取类属性;但类属性不能通过对象修改,在修改时,Python会自动为对象创建一个实例属性,并屏蔽掉类属性。
方法定义
- 类方法通过类名可以直接调用,与C++类方法类似。方法的第一个参数是cls。
- 实例方法要通过对象调用,与C++成员方法类似。方法的第一个参数是对象本身self。
构造/析构函数
- 函数__init__主要进行对象属性赋值等初始化操作,函数__del__主要在对象被Python垃圾回收时自动调用,通常不重写。
- 函数__init__中,必须显式调用父类的__init__方法,super(类名, self)返回父对象。
继承
- 继承可以让我们在子类中重用父类的属性、方法。
- 支持多继承class Class2(Class1, Class0, ...)
- 子类不重写__init__方法,在构造时会自动调用父类的__init__。
可见性控制
- 双下划线__开头的属性,代表是私有属性,无法被其它对象访问。
多态
- 通过在子类中重写父类中定义的方法,可以实现多态。与C++类似。
dir和__dict__和*attr
- 内置函数dir可以查看对象/模块的属性列表,对象的__dict__则显示对象的所有属性及属性的值(等价于内置函数vars)
- getattr(obj,objdata)可以获取一个对象的某个属性的值,如果属性不存在,可以返回一个给定的默认值。
- setattr用来设置对象属性的值,属性不存在时会为对象增加属性。
- delattr用来删除对象的属性。
- hasattr用来判断对象是否存在某个属性。
isinstance&issubclass
- isinstance(A,type)确定是否是指定类或者其子类的实例(或者type(obj)判断)。
- issubclass(A,B)判断A类是否是B类的直接或间接子类。
对象行为定制
- 针对Python特殊方法的方法重载,如__init__, __str__, __repr__, __It__, __add__, __radd__, __iadd__, __nonzero__。
Meta Class
- 类是对象,类的创建者是元类。
- type是python默认的元类。
- 可以定义type的子类,使用元类来创建新的类对象。
2.4 异常处理
- try - except ... as ... - else - finally
- Exception是所有内建异常类的基类,因此上述代码支持捕获大多异常。除了KeyboardInterrupt(用户中断执行Ctrl+C)和SystemExit(python解释器请求退出)不是由于代码执行错误引起的异常。
- 不要捕获并pass忽略所有错误,违背Fail Fast原则。
- 当finally中的所有代码都执行完毕后,如果异常在finally之前被捕获,则继续执行finally之后的代码;如果异常未被捕获,则该异常会继续向上层传递。如果finally中的代码引发了另一个异常或由于return、break、continue语句而终止,原来的异常将丢失。
- 异常向上层调用者移交异常机制。
- raise主动触发异常或向更高层传递异常。
- sys模块中的exc_info()函数提供异常信息:type(异常类),value(异常类实例),traceback(跟踪记录对象栈信息)
- 断言assert可触发AssertionError。
2.5 文件及文件处理
文件打开
- open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
- 文件编码和字符集,Unicode编码方案:utf32,utf16,utf8(自行学习)
文件函数
- close fileno flush isatty read readline readlines seek tell truncate write writelines
文件内容访问
典型的C编程的思维
line = f.readline()
while line:
print line
line = f.readline()
没有跟上时代的思维
for line in f.readlines():
print line
简洁、高效
for line in f:
print line
通过文件存储和加载对象
- pickle模块(对象的序列化)
import pickle
:
pickle.dump(x, f)
把对象x序列化后保存到文件f中
x = pickle.load(f)
从文件f中还原对象x
文件相关模块
拓展
- 标准流,在sys模块中预先打开的文件对象,如sys.stdout
- OS模块中的描述文件,支持文件锁定之类的较低级工具
- Sockets Pipe FIFO,文件类对象,用于同步进程或者网络通信
- Shell 命令流等
转载文章请标识和保留出处和署名,谢谢ヾ(•ω•`。)