• 函数是可重用的程序代码块,可复用,调用一致
  • 程序由一个个任务组成,函数则是具有明确目的一个任务或者功能的代码块
  • 函数是代码复用的通用机制

Python函数分类

  • 内置函数
    • str,list,len。。。
  • 标准库函数
    • Python库模块中的函数
  • 第三方库函数
    • 第三方库中的函数
  • 用户自定义函数

    函数定义

    1. def 函数名([参数列表]):
    2. """文档说明"""
    3. 函数体/执行语句
    4. return 返回值

    要点

  • 使用 def 定义函数 函数名代指函数

    • Python执行函数的时,会创建函数对象,并绑定到函数名变量上
  • 参数列表
    • 多个参数用逗号隔开
    • 形参,参数名不需要申明类型
    • 实参,具体传入的参数和形参一一对应
    • 参数传递为对象,即可以传入数值,字符串,序列,也可以是函数
  • return 返回值
    • return 可有可无
    • 函数需要返回值时,使用return 返回结果
    • 可以返回对象,即可返回函数,序列,具体数值,字符串

变量作用域

变量的作用范围成为变量的作用域,不同作用域的内同名变量之间相互不影响,变量分为

  • 全局变量
  • 局部变量

全局变量

  • 在函数和类定义之外声明的变量。作用域为定义的模块,从定义位置开始直到模块结束
  • 全局变量一般作为常量使用
  • 函数内要改变全局变量的值,使用 global 声明一下即可
  • 全局变量将死了函数的通用性和可读性,应该尽量避免使用全局变量

    局部变量

  • 在函数体中(包含形式参数),声明的变量,即为局部变量

  • 局部变量只在声明的函数或者对象中有效,函数执行完毕即被销毁
  • 局本部变量的引用比全局变量快,循环次数较多的情况下,优先考虑使用局部变量
  • 如果全局变量和局部变量同名,则函数就近原则会隐藏全局变量,只使用局部变量

参数传递

函数的参数传递的本质就是,从实参到形参的赋值操作
Python中一切皆对象,所有的赋值操作都是引用赋值,即参数传递都是引用传递,不是值传递
简单说,当参数或者对象发生传递的时候,实际上传递的是对象的地址,而不是对象的数据和结构
具体的参数传覅包括

  • 可变对象的传递,传递的原对象的地址,传递后的对象操作直接作用于原对象
  • 不可变对象传递,传递的是原对象复制份地址,传递后的对象直接作用于复制份对象,效果等同于值传递

可变对象:

  • 字典,集合,列表,自定义对象

不可变对象

  • 数字,字符串,元组,function

深/浅 拷贝

浅拷贝 不拷贝原对象子对象的内容,只拷贝子对象的引用,
对拷贝对象的子对象的操作会同步到原对象的子对象
对拷贝对象的操作,不会影响原对象
深拷贝 连子对象的内存全部拷贝一份,对子对象的修改不会影响原对象
对拷贝对象的操作也不会影响到原对象

传递不可变对象的时候是 浅拷贝
传递参数是不可变对象(int。float,字符串,元组,布尔)
实际传递的是对象的引用,但是在 写操作 的时候,会创建一个新的对象拷贝,此时是 浅拷贝,不是 深拷贝

类和对象

类的本质:事物的抽象
实例的本质:抽象事物的一次具体化
为什么需要类:因为需要高效,需要偷懒

类的结构

类有标准的结构,包括

  • 类属性 类的抽象层次特征
  • 类方法 类的抽象层次行为

类实例化后,即具体的通过类创建一个实例对象后,类的属性和方法会被实例继承

构造函数 init()

类中,实际上是由各个类方法(类中的函数)组成,其中类中的构造函数比较特殊
构造函数,是类的一部分组成,用于在类中初始化创建对象,即类在实例化的过程中,通过该方法对新建的实例初始化

Python对象包含三部分

  • id 对象编号/识别码
  • type 对象类型
  • value 对象的值
    • 属性 attribute
    • 方法 method

通过类创建实例对象时,需要定义构造函数 init() 方法,用于执行 实例对象初始化

init() 要点

  • 名称固定,必须为:init()
  • 该函数的第一个参数固定,为 self, self代指创建的实例对象
  • 构造函数通常用来初始化实例对象的实例属性
  • 通过 类名(参数列表),来调用构造函数,调用后即将实例属性返回非相应的变量

实例属性和方法

实例属性

实例属性是从属于实例对象的属性,也称为“实例变量”。他的使用有如下几个要点:

  1. 实例属性一般在init()方法中通过如下代码定义:

self.实例属性名 = 初始值

  1. 在本类的其他实例方法中,也是通过 self 进行访问:

self.实例属性名

  1. 创建实例对象后,通过实例对象访问:

obj01 = 类名() #创建对象,调用init()初始化属性
obj01.实例属性名 = 值 #可以给已有属性赋值,也可以新加属性

实例方法

实例方法是从属于实例对象的方法。实例方法的定义格式如下:
def 方法名(self [, 形参列表]):
函数体
方法的调用格式如下:
对象.方法名([实参列表])
要点:
1. 定义实例方法时,第一个参数必须为 self。和前面一样,self 指当前的实例对象。
2. 调用实例方法时,不需要也不能给 self 传参。self 由解释器自动传参。

· 函数和方法的区别
1. 都是用来完成一个功能的语句块,本质一样。
2. 方法调用时,通过对象来调用。方法从属于特定实例对象,普通函数没有这个特点。
3. 直观上看,方法定义时需要传递 self,函数不需要。

· 实例对象的方法调用本质:
image.png
· 其他操作: **
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 是所有类的父类

类成员的继承和重写

成员继承:
子类继承了父类除构造方法方法以外的所有成员

方法重写:
子类可以根据需要重新定义父类中的方法,这样就会覆盖父类的方法,称之为 方法重写
在子类中定义和父类中相同的名称的方法时,就会覆盖父类中对应的方法,即重写

多态

多态,即同一个方法调用由于不同的对象会产生不同的行为