- 函数是可重用的程序代码块,可复用,调用一致
- 程序由一个个任务组成,函数则是具有明确目的一个任务或者功能的代码块
- 函数是代码复用的通用机制
Python函数分类
- 内置函数
- str,list,len。。。
- 标准库函数
- Python库模块中的函数
- 第三方库函数
- 第三方库中的函数
-
函数定义
def 函数名([参数列表]):"""文档说明"""函数体/执行语句return 返回值
要点
使用 def 定义函数 函数名代指函数
- Python执行函数的时,会创建函数对象,并绑定到函数名变量上
- 参数列表
- 多个参数用逗号隔开
- 形参,参数名不需要申明类型
- 实参,具体传入的参数和形参一一对应
- 参数传递为对象,即可以传入数值,字符串,序列,也可以是函数
- return 返回值
- return 可有可无
- 函数需要返回值时,使用return 返回结果
- 可以返回对象,即可返回函数,序列,具体数值,字符串
变量作用域
变量的作用范围成为变量的作用域,不同作用域的内同名变量之间相互不影响,变量分为
- 全局变量
- 局部变量
全局变量
- 在函数和类定义之外声明的变量。作用域为定义的模块,从定义位置开始直到模块结束
- 全局变量一般作为常量使用
- 函数内要改变全局变量的值,使用 global 声明一下即可
全局变量将死了函数的通用性和可读性,应该尽量避免使用全局变量
局部变量
在函数体中(包含形式参数),声明的变量,即为局部变量
- 局部变量只在声明的函数或者对象中有效,函数执行完毕即被销毁
- 局本部变量的引用比全局变量快,循环次数较多的情况下,优先考虑使用局部变量
- 如果全局变量和局部变量同名,则函数就近原则会隐藏全局变量,只使用局部变量
参数传递
函数的参数传递的本质就是,从实参到形参的赋值操作
Python中一切皆对象,所有的赋值操作都是引用赋值,即参数传递都是引用传递,不是值传递
简单说,当参数或者对象发生传递的时候,实际上传递的是对象的地址,而不是对象的数据和结构
具体的参数传覅包括
- 可变对象的传递,传递的原对象的地址,传递后的对象操作直接作用于原对象
- 不可变对象传递,传递的是原对象复制份地址,传递后的对象直接作用于复制份对象,效果等同于值传递
可变对象:
- 字典,集合,列表,自定义对象
不可变对象
- 数字,字符串,元组,function
深/浅 拷贝
浅拷贝 不拷贝原对象子对象的内容,只拷贝子对象的引用,
对拷贝对象的子对象的操作会同步到原对象的子对象
对拷贝对象的操作,不会影响原对象
深拷贝 连子对象的内存全部拷贝一份,对子对象的修改不会影响原对象
对拷贝对象的操作也不会影响到原对象
传递不可变对象的时候是 浅拷贝
传递参数是不可变对象(int。float,字符串,元组,布尔)
实际传递的是对象的引用,但是在 写操作 的时候,会创建一个新的对象拷贝,此时是 浅拷贝,不是 深拷贝
类和对象
类的本质:事物的抽象
实例的本质:抽象事物的一次具体化
为什么需要类:因为需要高效,需要偷懒
类的结构
类有标准的结构,包括
- 类属性 类的抽象层次特征
- 类方法 类的抽象层次行为
类实例化后,即具体的通过类创建一个实例对象后,类的属性和方法会被实例继承
构造函数 init()
类中,实际上是由各个类方法(类中的函数)组成,其中类中的构造函数比较特殊
构造函数,是类的一部分组成,用于在类中初始化创建对象,即类在实例化的过程中,通过该方法对新建的实例初始化
Python对象包含三部分
- id 对象编号/识别码
- type 对象类型
- value 对象的值
- 属性 attribute
- 方法 method
通过类创建实例对象时,需要定义构造函数 init() 方法,用于执行 实例对象初始化
init() 要点
- 名称固定,必须为:init()
- 该函数的第一个参数固定,为 self, self代指创建的实例对象
- 构造函数通常用来初始化实例对象的实例属性
- 通过 类名(参数列表),来调用构造函数,调用后即将实例属性返回非相应的变量
实例属性和方法
实例属性
实例属性是从属于实例对象的属性,也称为“实例变量”。他的使用有如下几个要点:
- 实例属性一般在init()方法中通过如下代码定义:
self.实例属性名 = 初始值
- 在本类的其他实例方法中,也是通过 self 进行访问:
self.实例属性名
- 创建实例对象后,通过实例对象访问:
obj01 = 类名() #创建对象,调用init()初始化属性
obj01.实例属性名 = 值 #可以给已有属性赋值,也可以新加属性
实例方法
实例方法是从属于实例对象的方法。实例方法的定义格式如下:
def 方法名(self [, 形参列表]):
函数体
方法的调用格式如下:
对象.方法名([实参列表])
要点:
1. 定义实例方法时,第一个参数必须为 self。和前面一样,self 指当前的实例对象。
2. 调用实例方法时,不需要也不能给 self 传参。self 由解释器自动传参。
· 函数和方法的区别
1. 都是用来完成一个功能的语句块,本质一样。
2. 方法调用时,通过对象来调用。方法从属于特定实例对象,普通函数没有这个特点。
3. 直观上看,方法定义时需要传递 self,函数不需要。
· 实例对象的方法调用本质: 
· 其他操作: **
1. dir(obj)可以获得对象的所有属性、方法
2. obj.dict 获取对象的属性字典
3. pass 空语句
4. isinstance(对象,类型) 判断“对象”是不是“指定类型”
类对象
在Python 中,自定义的类,均是由 Type 实例化而来
类属性和类方法
类属性
类属性是从属于“类对象”的属性,也称为“类变量”。由于,类属性从属于类对象,可以 被所有实例对象共享。
类属性的定义方式:
class 类名:
类变量名= 初始值
在类中或者类的外面,我们可以通过:“类名.类变量名”来读写。
类方法
类方法是从属于“类对象”的方法。主要用来操作类属性
类方法通过装饰器@classmethod 来定义,格式如下:
@classmethod
def 类方法名(cls [,形参列表]) :
函数体
要点如下:
1. @classmethod 必须位于方法上面一行
2. 第一个 cls 必须有;cls 指的就是“类对象”本身;
3. 调用类方法格式:“类名.类方法名(参数列表)”。 参数列表中,不需要也不能给 cls 传 值。
4. 类方法中访问实例属性和实例方法会导致错误
5. 子类继承父类方法时,传入 cls 是子类对象,而非父类对象
静态方法
Python 中允许定义与“类对象”无关的方法,称为“静态方法”。
“静态方法”和在模块中定义普通函数没有区别,只不过“静态方法”放到了“类的名字空 间里面”,需要通过“类调用”。
静态方法通过装饰器@staticmethod 来定义,格式如下:
@staticmethod
def 静态方法名([形参列表]) :
函数体
要点如下:
1. @staticmethod 必须位于方法上面一行
2. 调用静态方法格式:“类名.静态方法名(参数列表)”。
3. 静态方法中访问实例属性和实例方法会导致错误
析构方法 del()
可调用对象 call()
私有属性
私有方法
装饰器
装饰器的本质,在对象或者函数执行前,嵌套一层操作
继承封装多态
封装
封装,隐藏对象的属性和方法的实现细节,只对外提供必要的方法
隐藏细节,只对外暴露 “相关的调用方法”
继承
- 继承可以让子类具父类的特性,提高代码的重用性
- 原有父类设计不变的情况下,可以增加新功能,或者改进已有的算法
- 原有的类称为“父类/基类”,新类称为“子类/派生类”
- 继承可以进行多重继承,一个子类可以有多个父类
- 如果在类定义中,没有指定继承父类,则默认父类是 object 即object 是所有类的父类
类成员的继承和重写
成员继承:
子类继承了父类除构造方法方法以外的所有成员
方法重写:
子类可以根据需要重新定义父类中的方法,这样就会覆盖父类的方法,称之为 方法重写
在子类中定义和父类中相同的名称的方法时,就会覆盖父类中对应的方法,即重写
多态
多态,即同一个方法调用由于不同的对象会产生不同的行为
