### python

变量定义*变量名=值

  • 变量核函数名由字母下划线、数字组成,
  • 不能以数字开头
  • 规则:以小写命名用下划线连接或采驼峰命名法
  • 定义变量时要做到见名知意
  • 使用Ctrl+Q可查看函数说明信息

数据类型可分为:数字型和非数字型

1.数字型:整型(int)、 浮点型(float)、布尔型(bool、 非零即真)、复数型(complex)
2.主要用于科学计算
3.非数字型:字符串、列表、元祖、字典可使用type()查看数据类型
4.input()输入的为字符型,若想输入数字进行运算则需要将其进行类型转换

元祖(Tuple) 列表(List )

1.列表:列表名+[]、列表是有序对象的集合。列表中用列表名+. tindex (“数据”) 确定据在列表中的位置
一、列表插入:
1.append (末位插入)
2.insert (指定位置插入)
3.extend (合并列表)
二、列表数据删除:
1.知道元素名用remove (“指定数据删除”)
2.知道元素位置用pop (“默认删除列表最后一个数据/也可指定” )
3.清空列表: clear ()
4.del () “del是一个关键字”del+列表名[元素代号],若del+列表名直接删除变量!
注:pop与del的区别如果你要从列表中删除一个元素,且不再使用它,就使用del语句;如果在删除后你还想继续使用它就用pop语句。remove()只删除第一个指定的值。如果要删除的值在列表中出现多次,就需要用循环来判断是否删除了所有这样的值。
三、求列表长度: len (列表名)
四、统计出现次数:列表名+count(“计算名”)
五、列表排序:
1.升序:列表名.sort () 永久性排序
2.降序:列表名.sort(reverse=true)
3.sorted()可保留原有的排列顺序 –即:暂时性排序
4.反转(逆序):列表名.reverse()
元祖:字典名+()大多于有关函数的参数和返回值、保护数据安全不被修改
常用操作: count()、 index()
注:元祖内的数据不能修改
**重点 **列内存储相同的数据便于执行相同的操作,而元祖在不确定数据类型的情况下能对其进行相同操作
列表与元祖之间的类型转换
元祖转为列表:列表名= list(需转换元组名)
列表转为元祖:元组名= tuple(需转换的列表名)

字典

字典:用{“key”:value} key必须唯一, 值可以为任意类型。字典是无序对象的集合,因此字典不能进行排序
迭代遍历字典 :for k in字典: (变量k是每次循环中获取到键值对的key)
字典的常用操作
1.居中.center()
2.计算长度.count()

字符类型

1.字符的定义:可用 “” 也可用 ‘ ‘
转义字符:\ 反斜杠号、' 单引号、
2." 双引号、\n 换行、\t 横向制表符(使输出的文本在垂直方向保持对其)、\r 代表回车
3.是否为数字类型 .isdecimal()、.isdigit()可判断序号、.isnumericc(可判断中文数字)
注:不能判断小数,返回类型为bool
4.由is开头的函数基本表示判断
5.大小写转换
方法 说明
.capitalize() 把字符串的第一个字符大写
.title() 把字符串的每个首字母大写
lower() 转换string中所有大写字符为小写
upper() 转换string中的小写字母为大写
swapcase() 反转string中的大小写
6.文本对齐:
.just(width) 返回一行个原字符串左对齐,并使用空格填充至长度width的新字符串
.rjust(width) 返回一行个原字符串右对齐,并使用空格填充至长度width的新字符串
.center(width) 返回一行个原字符串居中,并使用空格填充至长度width的新字符串
7.去除空白字符:
.lstrip() 截掉string左边(开始)的空白字符
.rstrp() 截掉string右边(末尾)的空白字符
.strip() 截掉string左右两边的空白字符
8.查找偷换:
.startswith(str) 检查字符串是否以str开头,返回bool型
.endswith(str) 检查字符串是否以str结束,返回bool型
.find(str,str=0,end=len(string)) 检测str是否包含在string中,如果start和end指定范围内,则检查是否包含在指定范围内,如果是返回索引值,否则返回 -1
.replace(old_str,new_str,num=strinng.count(old)) 把string中的old_str 替换成 new_str,如果num指定,则替换不能超过num次
9.切片:使用索引值来限定范围,从大的字符串切出小的字符串可顺,可倒取(-1、-2)列表名[起始值:结束值:步长]

公共方法

1.针对高级数据类型可使用的函数:
len() 计算容器中的元素个数
del()删除变量
max()返回容器中的元素最大值,如果是字典针对key进行比较
min()返回容器中的元素最小值
cmp()python3.x取消了cmp函数
2.完整的for循环:

for 变量 in 集合:  
    循环体代码
    else:
    没有通过break退出循环,循环结束后会执行的代码

应用场景:在迭代遍历嵌套的数据类型时,例如-个列表包含了多个字典
需求: 要判断某一个字典中是否存在指定的值
。如果存在,提示并且退出循环
。如果不存在,在循环整体结束后,希望得到一个统-的提示

变量的引用

●变量和数据都是保存在内存中的
●在Python中函数的参数传递以及返回值都是靠引用传递的
1.引用的概念
在Python中
●变量和数据是分开存储的
●数据保存在内存中的个位置
●变量中保存着数据在内存中的地址.变量中记录数据的地址,就叫做引用
●使用**id()**函数可以查看变中保存数据所在的内存地址
注意:如果变量已经被定义,当给一个变量赋值的时候,本质上是修改了数据的引用
●变量不再对之前的数据引用
●变量改为对新赋值的数据引用

可变和不可变类型

●不可变类型,内存中的数据不允许被修改:
●数字类型 int, bool, float, complex ,long(12.x)
●字符串 str
●元组 tuple
●可变类型,内存中的数据可以被修改:
●列表list
●字典dict——可以使用不可变类型作为键值对的key而不可以使用可变类型作为键值对的key

哈希(hash)

●Python 中内置有一一个名字叫做hash() 的函数
●接收一个不可变类型的数据作为参数。返回结果是一个整数
●哈希是一种算法,其作用就是提取数据的特征码(指纹)
●相同的内容得到相同的结果。不同的内容得到不同的结果

●在Python 中,设置字典的键值对时,会首先对key进行hash已决定如何在内存中保存字典的数据,以方便后续对字典的操作:增、删、改、查
●键值对的key必须是不可变类型数据
●键值对的value可以是任意类型的数据

局部变量和全局变量

●局部变量是在函数内部定义的变量,只能在函数内部使用
●全局变量是在函数外部定义的变量(没有定义在某一个函数内),所有函数内部都可以使用这个变量
提示:在其他的开发语言中,大多不推荐使用全局变量–可变范围太大,导致程序不好维护!
2.局部变量
●局部变量是在函数内部定义的变量,只能在函数内部使用
●函数执行结束后,函数内部的局部变量,会被系统回收
●不同的函数,可以定义相同的名字的局部变量,但是各用个的不会产生影响
2.局部变的作用
●在函数内部使用,临时保存函数内部需要使用的数据
3.局部变量的生命周期
●所谓生命周期就是变量从被创建到被系统回收的过程
●局部变量在函数执行时才会被创建
●函数执行结束后局部变量被系统回收
●局部变量在生命周期内,可以用来存储函数内部临时使用到的数据

3.全局变量
1)函数不能直接修改全局变的引用
●全局变量是在函数外部定义的变量(没有定义在某一个函数内),所有函数内部都可以使用这个变量
提示:在其他的开发语言中,大多不推荐使用全局变量–可变范围太大,导致程序不好维护!
●在函数内部,可以通过全局变量的引用获取对应的数据
●但是,不允许直接修改全局变量的引用–使用赋值语句修改全局变量的值。如果使用赋值语句只是定义了一个局部变量
2)在函数内部修改全局变量的值

在一个函数中对全局变量进行修改的时候,到底是否需安使用globai进行说明要看是否对全局变量的执行指向进行了修改,如果修改了执行,即让全局变量指向了一个新的地方,那么必须使用global如果,仅仅是修改了指向的空间中的数据,此时不用必须使用global
●注意:为了区分全局变量和局部变量通常在全局变量前添加 g_ 或 gl_名
●如果在函数中需要修改全局变量,需要使用global进行申明——global+变量名

函数参数和返回值的作用

1.函数根据有没有参数以及有没有返回值,可以相互组合,一共有4种组合形式
1)无参数无返回值
2)无参数,有返回值
3)有参数无返回值
4)有参数有返回值
2.定义函数时, 是否接收参数,或者是否返回结果,是根据实际的功能需求来决定的!
3.如果函数内部处理的数据不确定,就可以将外界的数据以参数传递到函数内部
3.如果希望一个函数执行完成后,向外界汇报执行结果,就可以增加函数的返回值
4.可用多个变量一次性接收返回的多个值(返回多少个值就定义多少变量接收)

交换两个数

1)使用其他变量,如:(a = num1,b= num2 ==> c = a,a= b,b=c)
2) 不使用其他变量,如:(a=num1,b=num2,a=a+b,b=a-b,a=a-b)
3)python专有解法元组:a, b=(b, a)
注:+=操作——列表做+=操作时本质上是调用extend方法(不是做先相加再赋值)

缺省参数

●定义函数时,可以给某个参数指定一个默认值,具有默认值的参数就叫做缺省参数
.调用函数时,如果没有传入缺省参数的值,则在函数内部使用定义函数时指定的参数默认值
●函数的缺省参数,将常见的值设置为参数的缺省值,从而简化函数的调用
●指定函数的缺省参数在参数后使用赋值语句,可以指定参数的缺省值
注:1.缺省参数,需要使用最常见的值作为默认值!
2.如果一个参数的值不能确定,则不应该设置默认值,具体的数值在调用函数时,由外界传递!
缺省参数的注意事项
1)缺省参数的定义位置
●必须保证带有默认值的缺省参数在参数列表未尾.
2)调用带有多个缺省参数的函数
●在调用函数时,如果有多个缺省参数,需要指定参数名,这样解释器才能够知道参数的对应关系!

多值参数(知道)
定义支持多值参数的函数
●有时可能需要一个通数 能够处理的参数个数是不确定的, 这个时候,就可以使用多值参数
●python中有两种多值参数:
● 参数名前增加一个 * 可以接收元组、参数名前增加两个* 可以接收字典
●一般在给多值参数命名时,习惯使用以下两个名字
* args–存放元组参数,前面有一个 *
**kuargs–存放字典参数,前面有两个 *
●args是arguments 的缩写,有变量的含义
●kw是keyword的缩写,kowargs 可以记忆键值对参数

字典与元组拆包:

在调用带有多个值 的函数时,如果希望将一个元组变量,直接传给形参元组,将一个字典变量直接传给形参字典则使用拆包,简化参数的传递——拆包方式:在元组变量前加一个 * ,在字典变量前加两个 *

递归:

特点 : 一个函数 内部自己调用自己(也可调用其他函数)、递归内部的代码是相同的,只是针对 参数不同,处理的结果不同、当参数满足一个条件时,函数不再执行重要,满足的条件通常被称为递归调用的出口,否则会陷入死循环!”

面向对象(OOP)基本概念

面向对象编程– 0bject Or iented Programing简写OOP
目标
●了解面向对象基本概念
01.面向对象基本概念
●我们之前学习的编程方式就是面向过程的
●面相过程和面相对象,是两种不同的编程方式
●对比面向过程的特点,可以更好地了解什么是面向对象
1.1过程和函数(科普)
●过程是早期的一个编程概念
●过程类似于函数,只能执行,但是没有返回值
●函数不仅能执行,还可以返回结果

1.2面相过程和面相对象基本概念

  1. 面相过程–怎么做?
    1.把完成某一个需求的所有步骤从头到尾逐步实现
    2.根据开发需求,将某些功能独立的代码封装成一个又个函数
    3.最后完成的代码,就是顶序地调用不同的函数
    特点
    1.注重步骤与过程不注重职责分工
    2.如果需求复杂,代码会变得很复杂
    3.开发复杂项目,没有固定的套路,开发难度很大

  2. 面向对象–谁来做?
    相比较函数, 面向对象是更大的封装,根据职责在一个对象中封装多个方法
    1.在完成某一个需求前,首先确定职责一-要做的事情(方法)
    2根据职责确定不同的对象,在对象内部封装不同的方法(多个)
    3.最后完成的代码,就是顶序地让不同的对象调用不同的方法特点
    1.注重对象和职责,不同的对象承担不同的职责
    2.更加适合应对复杂的需求变化,是专门应对复杂项目开发,提供的固定套路
    3.需要在面向过程基础上,再学习一些面向对象的语法

类和对象

01.类和对象的概念
类和对象是面向对象编程的两个核心概念
1.1类
●类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用
。特征被称为属性。行为被称为方法
.带就相当干制岩飞机时的用纸是一 个槽板是负表创建对象的

1.2对象
●对象是由类创建出来的一个具体存在可以直接使用
●由哪一个类创建出来的对象,就拥有在哪个类中定义的 * 属性 和 * 方法
●对象就相当于用图纸制造的飞机
在程序开发中,应该先有类,再有对象

02.类和对象的关系
●类是模板,对象是根据类这个模板创建出来的,应该先有类,再有对象
●类只有一个,而对象可以有很多个

  • 不同的对象之间属性可能会各不相同
    ●类中定义了什么属性和方法对象中就有什么属性和方法不可能多,也不可能少

03.类的设计
在使用面向对象开发前,应该先分析需求,确定一下程序中包含哪些类!
设计一个类通常满足三个要素:
●类名:满足大驼峰命名法(每个单词首字母大写、单词与单词之间没有下划线)定义方法:class 类名:后接def 方法1(self,参数)……
●属性:具有什么样的特征(对特征的描述)在开发中不推介使用在类的外部给对象增加属性
●方法:事物具有什么样的行为(方法)

3.1类名的确定
名词提炼法分析整个业务流程,出现的名词,通常就是找到的类

3.2属性和方法的确定
●对对象的特征描述,通常可以定义成属性
●对象具有的行为(动词),通常可以定义成方法
提示:需求中没有涉及的属性或者方法在设计类时,不需要考虑

面想对象的基础语法

01.dir内置函数(知道)
●在Python中对象几乎是无所不在的,我们之前学习的变量、数据、函数都是对象在Python中可以使用以下两个方法验证:

1.在标识符/数据后输入一个 . 然后按下TAB键,iPython 会提示该对象能够调用的方法列表
2.使用内置函数dir传入标识符/数据,可以查看对象内的所有属性及方法

提示_方法名_格式的方法是 Python提供的内方法/属性稍后会给大家介绍些常用的内置方法/属性
序号 方法名 类型 作用
01 _ new _ 方法 创建对象时,会被自动调用
02 _ init _ 方法 对象被初始化时,会被自动调用
03 _ del _ 方法 方法对象被从内存中销毁前, 会被自动调用方法
04 _ str _ 方法 返回对象的描述信息,print 函散输出使用

02.定义简单的类(只包含方法)
面向对象是更大的封装,在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了!
2.1定义只包含方法的类
●在Python中要定义一个只包含方法的类,语法格式如下:

class类名:
     
    def  方法1(self,参数列表):
            pass

    def  方法2(self,参数列表):
            pass

●方法的定义格式和之前学习过的函数几乎一样
●区别在于第一个参数必须是self
注意:类名的命名规则要符合大驼峰命名法

2.2对象创建
●当一个类似定义完成后,使用类来创建对象: 对象变量 = 类名()

引用极念的强调
在面向对象开发中 引用的概念是同样适用的!
●使用print输出对象变量,默认情况下,是能够输出这个变量引用的对象是由哪一个类创建的对象,以及在内存中的地址(十六进制表示)
提示在计算机中,通常使用十六进制表示内存地址
●十进制和十六进制都是用来表达数字的,只是表示的方式不样
●十进制和十六进制的数字之间可以来回转换
●%d可以以10进制输出数字
●%x可以以16进制输出数字

03.方法中的self参数
3.1案例改造–给对象增加属性
●在Python中,要给对象设置属性,非常的容易,但是不推荐使用

  • 因为:对象属性的封装应该封装在类的内部
    ●只需要在类的外部的代码中直接酒过,设置一个属性即可
    注意:这种方式虽然简单,但是不推荐使用!

3.2使用self在方法内部输出
由 哪一个对象调用的方法方法内的self 就是哪一个对象的引用
●在类封装的方法内部,self 就表示当前调用方法的对象自己
●调用方法时,程序员不需要传递self参数
●在方法内部

  • 可以通过self.访问对象的属性
  • 也可以通过self,调用其他的对象方法

04.初始化方法
4.1之前代码存在的问题–在类的外部给对象增加属性

  • 将案例代码进行调整,先调用方法再设置属性
    提示
    ●在日常开发中,不推荐在类的外部给对象增加属性
    。如果在运行时,没有找到属性,程序会报错
    ●对象应该包含有哪些属性,应该封装在类的内部

4.2初始化方法
●当使用类名(创建对象时,会自动执行以下操作:
1.为对象在内存中分配空间–创建对象
2.为对象的属性设初始值–初始化方法( init)
●这个初始化方法就是 _ init _ 方法, _ init _ 是对象的内置方法
_ init _ 方法是 专门用来定义一个类具有哪些属性的方法!

4.3在初始化方法内部定义属性
●在 _ init _ 方法内部使用! self.属性名=属性的物始值就可以定义属性
●定义属性之后,再使用别的类创建的对象,都会拥有该属性

4.4改造初始化方法–初始化的同时设置初始值
●在开发中,如果希望在创建对象的同时,就设对象的属性,可以对_ .nit_ 方法进行 改造
1.把希望设置的属性值,定义成 _ init _ 方法的参数
2.在方法内部使用self.属性=形参接收外部传递的参数
3.在创建对象时,使用类名(属性1, 属性2…)调用

05.内置方法和属性
序号 方法名 类型 作用
01 _ del _ 方法 対象被从内存中销毁前,会被自动调用
02 _ str _ 方法 返回対象的描述信息, print函数输出使用
5.1 _ del _ 方法(知道)

  • 在Python中
  • 当使用类名()创建対象吋,为対象分配完空同后,自动调用 _ init _ 方法
  • 当一个対象被从内存中销毀前,会自动调用 _ del _ 方法
  • 应用场景
  • _ init _ 改造初始化方法,可以让创建对象更加灵活
  • _ del _ 如果希望在対象被硝毀前,再做一些事情, 可以考虑一下 _ del _ ;方法
  • 生命周期
  • 一个对象从搞用类名() 创建,生命周期幵始
  • 一个对象的 _ del _ 方法一旦被调用,生命周期结束
  • 在对象的生命周期内,可以访问对象属性、或者让对象调用方法
    5.2 _ str _ 方法
    ●在Python中,使用print输出对象变量默认情况下,会输出这个变量引用的对象是由哪一个类创建的对象,以及在内存中的地址(十六进制表示)
    ●如果在开发中,希望使用print输出对象变量时,能够打印自定义的内容,就可以利用 _ str _ 这个内置方法了
    注意:_str_方法必须返回一个字符串

面想对象的封装

01.封装
1.封装是面向对象编程的大特点
2面向对象编程的第步一将属性和方法封装到一个抽象的类中
3.外界使用类创建对象然后让对象调用方法
4.对象方法的细节都被封装在类的内部
提示:1.在对象的方法内部,是可以直接访问对象的属性的
2.同一个类创建的多个对象之间,属性互不干扰!

私有属性和私有方法

01.应用场景及定义方式
应用场景
●在实际开发中,对象的某些属性或方法可能只希望在对象的内部被使用,而不希望在外部被访问到
●私有属性就是对象不希望公开的属性
●私有方法就是对象不希望公开的方法
定义方式
●在定义属性或方法时,在属性名或者方法名前增加两个下划线,定义的就是私有属性或方法

02.伪私有属性和私有方法(科普)
提示: 在日常开发中,不要使用这种方式访问对象的私有属性或私有方法
Pythad中,并没有真正意义的私有
●在给属性、方法命名时,实际是对名称做了一些特殊处理,使得外界无法访问到
●处理方式:在名称前面加上. _ 类名=> _ 类名 _ _ 名称

  • 在不希望公开的属性名或方法名前添加两个下划线(强制访问一个下划线+类名 +属性名或方法名)

继承

●单继承
●多继承

面向对象三大特性
1.封装极据职责将属性和方法封装到一个抽象的类中
2.继承实现代码的重用,相同的代码不需要重复的编写
3.多态不同的对象调用相同的方法,产生不同的执行结果,增加代码的灵活度

01.单继承
1.1继承的概念、语法和特点
继承的概念:子类拥有父类的所有方法和属性
1)继承的语法

class类名(父类名):
        pass

●子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发
●子类中应该根据职责,封装子类特有的属性和方法
2)专业术语
子类 = 派生类、父类 = 基类
3)继承的传递性
●C类从B类继承,B类又从A类继承
●那么C类就具有B类和A类的所有属性和方法
子类拥有父类以及父类的父类中封装的所有属性和方法

1.2方法的重写
●子类拥有父类的所有方法和属性
●子类继承自父类,可以直接享受父类中已经封装好的方法,不需要再次开发
应用场景
●当父类的方法实现不能满足子类需求时,可以对方法进行重写(verride)
重写父类方法有两种情况
1.覆盖父类的方法
2.对父类方法进行扩展
1)覆盖父类的方法
●如果在开发中,父类的方法实现和子类的方法实现完全不同.就可以使用覆盖的方式,在子类中重新编写父类的方法实现

  • 具体的实现方式, 就相当于在子类中定义了一个和父类同名的方法并且实现
  • 重写之后,在运行时,只会调用子类中重写的方法而不再会调用父类封装的方法
    2)对父类方法进行扩展
    ●如果在开发中,子类的方法实现中包含父类的方法实现
  • 父类原本封装的方法实现是子类方法的一部分
    ●就可以使用扩展的方式

1.在子类中重写父类的方法
2.在需要的位置使用super().父类方法 来调用父类方法的执行
3.代码其他的位置针对子类的需求,编写子类特有的代码实现

关于super
●在Python中super是一个特殊的类
●super()就是使用super类创建出来的对象
●最常使用的场景就是在重写父类方法时,调用在父类中封装的方法实现
提示:在开发时,父类名和 super() 两种方式不要混用。如果使用当前子类名调用方法会形成递归调用,出现死循环

1.3父类的私有属性和私有方法
1.子类对象不能在自己的方法内部,直接访问父类的私有属性或私有方法
2.子类对象可以通过父类的公有方法间接访问到私有属性或私有方法
●私有属性、方法是对象的隐私,不对外公开,外界以及子类都不能直接访问
●私有属性、方法通常用于做一些内部的事情

02.多继承
子类可以拥有多个父类并且所有父类的属性和方法
语法:

class 子类名(父类名1,父类名2…)
    pass

2.1多继承的使用注意事项
问题的提出
●如果不同的父类中存在同名的方法子类对象在调用方法时,会调用哪一个父类中的方法呢?
提示:开发时,应该尽量避免这种容易产生混淆的情况! –如果父类之间存在同名的属性或者方法,应该尽量避免使用多继承

Python中的MRO –方法搜索顺序(知道)
●Python中针对类提供了一个内置属性mro _ 可以查看方法搜索顶序
● MRO 是 ethod resolution order , 主要用于在多继承时判断方法、属性的调用踏径
print(c. _ mro _ )

输出结果
(<class’nain_ ,C’>, <class main_ .A’>, <class ‘sain_ .B’>, <class ‘object’>)

●在搜索方法时,是按照_ mnro_ 的输出结果从左至右的顺序查找的
●如果在当前类中找到方法,就直接执行,不再搜索
●如果没有找到,就查找下一个类中是否有对应的方法,如果找到,就直接执行,不再搜索
●如果找到最后一个类,还没有找到方法,程序报错

2.2新式类与旧式(经典)类
object是Python为所有对象提供的基类,提供有一些内置的属性和方法,可以使用dir函数查看
●新式类以obfect为基类的类,推荐使用
●经典类不以object为基类的类,不推荐使用
●在Python 3.x中定义类时,如果没有指定父类,会默认使用object作为该类的基类–
Python 3.x中定义的类都是新式类
●在Python 2.x中定义类时,如果没有指定父类,则不会以object 作为基类|新式类 和经典类在多继承时–会影响到方法的搜索顺序
●为了保证编写的代码能够同时在Python 2.x和Python 3.x运行!今后在定义类时,如果没有父类,建议统继承自abject

class类名(object):
       pass

多态

●多态
面向对象三大特性
1.封装根据积责将属性和方法封装到个抽象的类中
●定义类的准则
2.继承实现代码的用,相同的代码不需要重复的编写
●设计类的技巧
●子类针对自己特有的需求,编写特定的代码
3.多态不同的子类对象调用相同的父类方法,产生不同的执行结果
●多态可以增加代码的灵活度
●以继承和重写父类方法为前提
●是调用方法的技巧,不会影响到类的内部设计

1.1术语–实例
1.使用面相对象开发,第1步是设计类
2.使用类名()创建对象,创建对象的动作有两步
●1)在内存中为对象分配空间
●2)调用初始化方法_ init _为对象初始化
3.对象创建后,内存中就有了一一个对象的实实在在的存在–实例
因此,通常也会把
1.创建出来的对象叫做类的实例
2.创建对象的动作叫做实例化
3.对象的属性叫做实例属性
4.对象调用的方法叫做实例方法
在程序执行时:
1.对象各自拥有自己的实例属性
2.调用对象方法,可以通过self.
●访问自己的属性.调用自己的方法
结论
●每一个对象都有自己独立的内存空间,保存各自不同的属性
●多个对象的方法,在内存中只有份,在调用方法时,需要把对象的引用传递到方法内部

1.2类是一个特殊的对象
Python中一切皆对象:
●class AAA定义的类属于类对象
●obj1=AAA() 属于实例对象

●在程序运行时,类同样会被加载到内存
●在Python中类是一个特殊的对象–类对象
●在程序运行时,类对象在内存中只有一份,使用一个类可以创建出很多个对象实例
●除了封装实例的属性和方法外,类对象还可以拥有自己的属性和方法
1.类属性
2.类方法
●通过类名的方式可以访问类的属性或者调用类的方法

类名,属性 ——-> 类属性 该类的所
类名.方法名()—> 类方法(cls) 有对象共享通过类名直接访问

类名() ————-> _ init _ 定义实例属性
对象名,方法名() —-> 实例方法(self)

02.类属性和实例属性
2.1概念和使用
●类医性就是给类对象中定义的属性
●通常用来记录与这个类相关的特征
●类属性不会用于记录具体对象的特征
示例需求
●定义一个工具类
●每件工具都有自己的nane
●需求一-知道使用这个类,创建了多少个工具对象?
| Tool |
| Tool, countnane |
| init (self, name): |

2.2 属性获取机制
●在python中属性的获取存在一个向上查找机制
●因此,要访问雷属性有两种方式
类名.属性
对象名. 属性(不推荐)
如果使用 对象.属性 = 值 复制语句,只会给对象添加一个属性,而不会影响到类属性的值

03.类方法和静态方法
3.1类方法
●类属性就是针对类对象定义的属性
●使用赋值语句在class关键字下方可以定义类属性
●类属性用于记录与込个类相关的特征
●类方法就是针对类对象定义的方法
●在类方法内部可以直接访问类属性或者调用其他的类方法
语法如下

@classnethod
def  类方法名(cls)
    pass

●类方法需要用修饰器@classnethod来标识,告诉解释器这是一个类方法
●类方法的第1个参数应该是cls
。由哪一个类调用的方法,方法内的cls就是哪一个类的引用
。这个参数和实例方法的第一个参数是setf 类似
。提示使用其他名称也可以,不过习惯使用cls
●通过类名调用类方法调用方法时,不需要传递cls参数
●在方法内部
。可以通过cls. 访问类的属性
。也可以通过cls.调用其他的类方法

示例需求
●定义一个工具类
●每件工具都有自己的name
●需求–在类封装一个show tool .count 的类方法,输出使用当前这个类,创建的对象个数
Tool
TooL.count nane
init_(self, name):
show tool count(cls):

@classnethod
def show .tool count(cls):
     """显示工具对象的总数"""
     print("工具对象的总数"号cls. count)

在类方法内部,可以直接使用cls访问类属性或者调用类方法

3.2静态方法
●在开发时,如果需要在类中封装一个方法这个方法
。既不需要访问实例属性或者调用实例方法
。也不需要访问类属性或者调用类方法
●这个时候,可以把这个方法封装成一个静态方法
语法如下

@staticnethod
def静态方法名():
    pass

●静态方法需要用修饰器@staticnethod 来标识,告诉解释器这是一个静态方法
●通过类名.调用静态方法 - 不需要创建对象
小结
1.实例方法–方法内部需要访问案例属性
。案例方法内部可以使用类名.访问类属性
2.类方法–方法内部只需要访问类属性
3.静态方法–方法内部、不需要访问案例属性和类属性
如果方法内部即需要访问案例属性,又需要访问类属性,以该定义成什幺方法?
答案:
。应该定义案例方法
。因为,类只有一个、在案例方法内部可以使用类名.访问类属性

单例

单例设计模式
● _ new _ 方法
● Python中的单例

01.单例设计模式
●设计模式
。设计模式是前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对某特定问题的成熟的解决方案
。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性

●单例设计模式
。目的一-让类创建的对象,在系统中只有唯一的一个实例
。每一次执行类名()返回的对象,内存地址是相同的

单例设计模式的应用场景
●音乐播放对象
●回收站对象
●打印机对象

02._ new_ 方法

  • 使用类名()创建对象吋,python 的解释器首先会调用 _ new _ 方法为对象 分配空间
  • _ new 是一↑由object基类提供的内置的静态方法,主要作用有两个:
    1)在内存中为对象分配空间。
    2)返回对象的引用
    ● Python 的解释器获得对象的引用后,將引用作为第一个参数,传递给 _ init _ 方法
    重写
    new _ 方法的代碣非常固定!
    ●重写_new
    方法一定要 return super0._ _new _ clsl
    ●否則Python的解釋器得不到分配了空伺的対象引用,就不会洞用対象的初始化方法 ●注意: _ new是一个静态方法,在调用吋需要主动传递cls参数
  1. Python中的单例
    ●单例–让类创建的对象,在系统中只有唯一的一个实例
    1.定义一个类属性,初始值是None,用于记录单例对象的引用
    2.重写 _ new _ 方法
    3.如果类属性is None,调用父类方法分配空间,并在类属性中记录结果
    4.返回类属性中记录的对象引用

    class MusicPlayer (object):
      #要定文类属性记录单例对象引用
      instance = None
      def . new_ (cLs, args。kwargs):
       #1.判断类属性是否已经被赋值
         if cls. instance is Mone:
          cls.instance = super()._ new _(cls)

     # 返回类型的单例引用
      return cls.instance

只执行一次初始化工作
●在每次使用类名()创建对象时,Python 的解释器都会自动调用两个方法:
●_ new 分配空间_
●init _ 对象初始化
●在上一小节对 _ new_ _ 方法改造之后,每次都会得到第一次被创建对象的引用
●但是:初始化方法还会被再次调用
需求
●让初始化动作只被执行次
解决办法
1.定义一个类属性init _ fLag标记是否执行过初始化动作,初始值为False
2.在 _ _ init _ _ 方法中,判断init, flag,如果为False就执行视始化动作 3.然后将init _ flag 设置为True
4.这样,再次自动调用_ _init _ 方法时, 初始化动作就不会被再次执行了

异常处理

1.捕获异常
简单的捕获异常语法
在程序开发中,如果对某些代码的执行不能确定是否正确, 可以增加try(尝试) 来捕获异常
●捕获异常最简单的语法格式:

try:

   尝试执行的代码
except:

    出现错误的处理

●try尝试,下方编写要尝试的不确定是否能够正常执行的代码
●except如果不是,下方编写尝试失败的代码
简单异常捕获演练–要求用户输入整数

  try:
  #提示用户输入一个数字
      num = int(input("请输入数字"))
  except:
      print("请输入正确的数字”)

2.错误类型捕获
●在程序执行时,可能会遇到不同类型的异常,并且需要针对不同类型的异常,做出不同的响应,这个时候,就需要捕获错误类型了
●语法如下:

 try:
       pass
 except  错误类型1:
        # 单针对错误类型1,对应的代码处里
        pass
 except   (错误类型2,错误类型3):
          # 单针对镇误类型2和3,对应的代码处理
        pass
 except Exception as result:
        print("未知错误 %s” % result)

●当Python 解释器抛出异常时,最后一行错误信息的第一个单词, 就是错误类型
异常类型捕获演练

3.捕获未知错误
●在开发时,要预判到所有可能出现的错误,还是有一定难度的
●如果希望程序无论出现任何错误都不会因为Python解释器抛出异常而被终止,可以再增加个except
语法如下:

 except Exception as result:
            print("未知错误 %s” % result)

3.异常捕获完整语法
在实际开发中为了能够处理复杂异常的情况,完整的异常处理语法如下:

try:
        # 尝试执行的代码
        pass
except  错误类型1:
        # 针对错误类型1对应的代码处理
        pass
except  错误类型2:
        # 针对错误类型2对应的代码处理
        pass
except  Exception as result:
        # 打印错误信息
        print(result)
else:
        # 没有异常才会处理的代码
        pass
finally:
        # 无论是否异常都会执行的代码
        print("无论是否异常都会执行的代码")
  • else 只有在没有异常时才会被执行的代码
  • finall 无论是否异常都会执行的代码

4.异常的传递
●异常的传递一-当函数方法执行出现异常,会将异常传递给函数/方法的调用一方.如果传递到主程序仍然没有异常处理,程序才会被终止
提示
●在开发中,可以在主函数中增加异常捕获
●而在主函数中调用的其他函数,只要出现异常,都会传递到主函数的异常捕获中
●这样就不需要在代码中,增加大量的异常捕获能够保证代码的整洁
抛出异常
●Python中提供了一个Exception异常类
●在开发时,如果满足特定业务需求时,希望抛出异常,可以:
1.创建一个Exception的对象
2.使用raise关键字抛出异常对象
如:登录模块的密码,密码长度小于8直接抛出异常

模块

1)在导入模块时可以给模块取别名
语法:import 模块名 as 替代名
2)from…import 导入
●如果希望从某一个模块中导入部分工具,就可以使用from…import的方式
●import 模块名是一次性八模块中所有工具全部导入,并通过模块/别名访问
语法:from 模块名 import 工具名
●导入模块后不需要通过模块名,可以直接使用模块提供的工具——全局变量,函数,类
●注:如果导入的模块中存在同名函数,后导入的模块会覆盖先导入的模块。
解决:通过as取别名
3)form…import *
●注:这种方式不推荐使用,因为函数名重复没有任何提示,出现问题难以排查
在给模块命名时不要与系统模块名重复,因为模块使用时是先在文件夹里搜寻。可用prin( 模块名 ._ _ file _ _ )查询模块的根目录

1.原则–每一一个文件都应该是可以被导入的
●一个独立的Python文件就是一个模块
●在导入文件时,文件中所有没有任何缩进的代码都会被执行一遍

实际开发场景
●在实际开发中,每一个模块都是独立开发的,大多都有专人负责.开发人员通常会在模块下方增加一些测试代码
●仅在模块内使用,而被导入到其他文件中不需要执行
_ _ name _ _ 属性
● _ _ name _ _ 属性可以做到,测试模块的代码只在测试情况下被运行,而在被导入时不会被执行!
● _ name _ _ 是Python的个内置属性,记录着一个字符串
●如果是被其他文件导入的,
_ nare _ _ 就是 模块名
●如果是当前执行的程序 _ _ name _ _ 是 _ _ main _ _

2.包(Package)
概念
●包是一个包含多个模块的特殊目录.目录下有一个特殊的文件 _ init _ .py
●包名的命名方式和变量名一致,小写字母+ _
好处
●使用import包名I可以一次性导入包中所有的模块
_ _ init _ _ .py
●要在外界使用包中的模块,需要在 _ _ init _ _ .py中指定 对外界提供的模块列表

#从当前目录导入模块列表
from . import       send._message
from.import receive_nessage

pip安装第三方模块
●第三方模块通常是指由知名的第三方团队开发的并且被程序员广泛使用的Python 包/模块
●例如pygare就是一套非常成熟的游戏开发模块
●pip是一个现代的,通用的Python包管理工具
●提供了对Python包的查找、下载、安装、卸载等功能

安装和卸载命令如下:

# 将模块安装到Python 2.x环境
$ sudo pip install pygame
$ sudo pip uninstall pygame

# 将模块安装到Python 3.x环境
$ sudo pip3 install pygame
$ sudo pip3 uninstall Pygame(卸载)

在Mac下安装iPython

 $ sudo pip install ipython

在Linux下安装iPython

$ sudo apt install ipython
$ sudo apt install ipython3
文章作者: 南方Mr. Yu🍂
文章链接: https://yuyv.xyz/2019/01/21/%E5%9F%BA%E7%A1%80/python%20%E6%80%BB%E7%BB%93/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 一只小可乐!