赞
踩
含义:在代码中,被写下来的的固定的值,称之为字面量
注释:在程序代码中对程序代码进行解释说明的文字。
作用:注释不是程序,不能被执行,只是对程序代码进行解释说明,让别人可以看懂程序代码的作用,能够大大增强程序的可读性。
以 #开头,#右边 的所有文字当作说明,而不是真正要执行的程序,起辅助说明作用
以一对三个双引号引起来 (“”“注释内容”“”)来解释说明一段代码的作用使用方法
变量:在程序运行时,能储存计算结果或能表示值的抽象概念。
特征:变量存储的数据,是可以发生改变的。(为了重复使用)
通过type()语句来得到数据的类型:
type(被查看类型的数据)
如:
标识符:是用户在编程的时候所使用的一系列名字,用于给变量、类、方法等命名。
规则:内容限定 / 大小写敏感 / 不可使用关键字
命名中只允许出现英文 / 中文 / 数字 / 下划线这四类元素,其余任何内容都不被允许。
规范:见名知意 / 下划线命名法 / 英文字母全小写
如果定义的字符串本身包含单引号/双引号:
通过+号完成:
字符串无法和非字符串变量进行拼接,因为类型不一致,无法接上
通过**%s**,完成字符串和变量的快速拼接
python支持的常用数据类型占位:
浮点数19.99,变成了19.990000输出 — 需要“数字精度控制”
使用**辅助符号"m.n"**来控制数据的宽度和精度
示例:
%5d:表示将整数的宽度控制在5位,如数字11,被设置为5d,就会变成:[空格][空格][空格]11,用三个空格补足宽度。
%5.2f:表示将宽度控制为5,将小数点精度设置为2
小数点和小数部分也算入宽度计算。如,对11.345设置了%7.2f 后,结果是:[空格][空格]11.35。2个空格补足宽度,小数部分限制2位精度后,四舍五入为 .35
%.2f:表示不限制宽度,只设置小数点精度为2,如11.345设置%.2f后,结果是11.35
通过**f"内容{变量}"**的格式来快速格式化,不做精度控制,也不理会类型,适用于快速格式化字符串。
表达式:一个具有明确结果的代码语句,如 1 + 1、type(“字符串”)、3* 5等
在变量定义的时候,如 age = 11 + 11,等号右侧的就是表达式,也就是有具体的结果,将结果赋值给了等号左侧的变量
在无需使用变量进行数据存储的时候,可以直接格式化表达式,简化代码:
布尔类型的字面量:
有很多场景,不仅仅是多个并列条件,还会有满足前置条件才会二次判断的多层判断需求。
嵌套的关键点,在于:空格缩进,通过空格缩进来决定语句之间的:层次关系
while循环的循环条件是自定义的,自行控制循环条件;for循环是一种”轮询”机制,从待处理数据集中逐个取出数据赋值给临时变量。
range(num):获取一个从0开始,到num结束的数字序列(不含num本身) 如:range(5) — [0, 1, 2, 3, 4]
range(num1,num2):获得一个从num1开始,到num2结束的数字序列(不含num2本身) 如:range(5, 10) — [5, 6, 7, 8, 9]
range(num1, num2, step):获得一个从num1开始,到num2结束的数字序列(不含num2本身)数字之间的步长,以step为准(step默认为1) 如:range(5, 10, 2) — [5, 7, 9]
.for循环中的临时变量,其作用域限定为:循环内
和while循环一样,需要注意缩进,通过缩进确定层次关系
continue关键字:
break关键字:
函数:是组织好的,可重复使用的,用来实现特定功能的代码段。
优点:
函数名(参数)
传入参数:在函数进行计算的时候,接受外部(调用时)提供的数据
定义:
函数定义中的参数称为形式参数(形参),参数之间使用逗号分割。
函数调用中的参数称为实际参数(实参),按照顺序传入数据,使用逗号分隔。
传入参数的数量是不受限制的,可以不使用参数,也可以仅使用任意N个参数。
调用函数时根据函数定义的参数位置来传递参数
传递的参数和定义的参数的顺序及个数必须一致
函数调用时通过**“键=值”**形式传递参数.
作用: 可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
⭐ 函数调用时,如果有位置参数,必须在关键字参数的前面,但关键字参数间不存在先后顺序。
缺省参数(默认参数):用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值
作用:当调用函数时没有传递参数,就会使用默认是用缺省参数对应的值.
⭐ 所有位置参数必须出现在默认参数前,包括函数定义和调用
⭐ 函数调用时,如果为缺省参数传值,则修改默认参数值, 否则使用这个默认值。
不定长参数(可变参数):用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。
传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple)。
参数是**“键=值”的形式**的情况下, 所有的“键=值”都会被kwargs接受, 同时会根据“键=值”组成字典。
“返回值”,就是程序中函数完成事情后,最后给调用者的结果
⭐ 函数体在遇到return后就结束了,所以写在return后的代码不会执行。
按照返回值的顺序,写对应顺序的多个变量接收即可
变量之间用逗号隔开,支持不同类型的数据return
如果函数没有使用return语句返回数据,函数也有返回值。无返回值的函数,实际上就是返回了:None这个字面量,其类型是:<class ‘NoneType’>
用法:
通过多行注释的形式,对函数进行说明解释,其内容应写在函数体之前。
嵌套调用:一个函数里面又调用了另外一个函数
函数A中执行到调用函数B的语句,会将函数B全部执行完成后,继续执行函数A的剩余内容
作用域:变量的作用范围(变量在哪里可用,在哪里不可用)
局部变量:定义在函数体内部的变量,即只在函数体内部生效。
作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量。
全局变量:在函数体内、外都能生效的变量
使用global关键字可以在函数内部声明变量为全局变量
有名称的函数,可以基于名称重复使用;无名称的匿名函数,只可临时使用一次。
lambda 传入参数: 函数体(一行代码)
数据容器:一种可容纳多份数据的数据类型,容纳的每一份数据称之为1个元素。
每一个元素,可以是任意类型的数据,如字符串、数字、布尔等。
列表内的每一个数据,称之为元素。
列表[下标索引]:用于取出特定位置的元素
对于嵌套列表:
⭐ 下标索引的取值范围,超出范围无法取出元素,并且会报错。
列表.index(元素) | 查找指定元素在列表的下标,如果找不到,报错ValueError。 |
---|---|
列表[下标] = 值 | 直接对指定下标(正向、反向下标均可)的值进行:重新赋值(修改)。 |
列表.insert(下标, 元素) | 在指定的下标位置,插入指定的元素。 |
列表.append(元素) | 将指定元素,追加到列表的尾部。 |
列表.extend(其它数据容器) | 将其它数据容器的内容取出,依次追加到列表尾部。 |
del 列表[下标] | 删除元素 |
列表.pop(下标) | 删除元素 |
列表.clear() | 清空列表内容 |
列表.count(元素) | 统计某元素在列表内的数量 |
len(列表) | 统计列表共有多少元素 |
使用列表[下标]的方式取出列表元素
定义一个变量表示下标,从0开始,循环条件为 下标值 < 列表的元素数量
index = 0
while index < len(列表)
元素 = 列表[index]
对元素进行处理
index += 1
for 临时变量 in 数据容器:
对临时变量进行处理
定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型。
# 定义元组字面量
(元素, 元素, ..., 元素)
# 定义元组变量
变量名称 = (元素, 元素, ..., 元素)
# 定义空元组
变量名称 = () # 方式1
变量名称 = tuple() # 方式2
index() | 查找某个数据,如存在返回对应下标,否则报错 |
---|---|
count() | 统计某个数据在当前元组出现的次数 |
len(元组) | 统计元组内的元素个数 |
字符串:可以存放任意数量的字符。
字符串 — 无法修改
字符串.index(字符串) | 查找特定字符串的下标索引值 |
---|---|
字符串.replace(字符串1,字符串2) | 将字符串1全部替换为字符串2,得到了一个新字符串。 |
字符串.split(分隔符字符串) | 按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中。 |
字符串.strip() | 去前后空格 |
字符串.strip(字符串) | 去前后指定字符串(按照单个字符去除) |
字符串.count(字符串) | 统计字符串中某字符串的出现次数 |
len(字符串) | 统计字符串的长度 |
序列:内容连续、有序,可使用下标索引的一类数据容器。(如:列表、元组、新字符串)
序列[起始下标:结束下标:步长]:从序列指定位置开始,依次取出元素,到指定位置结束,得到一个新序列。
my_str="12345
new_str=my_str[::-1] #从头(最后)开始,到尾结束,步长-1(倒序)
print(new_str) #结果:“54321”
my_list = [1, 2, 3, 4, 5]
new_list = my_list[3:1:-1] #从下标3开始,到下标1(不含)结束,步长-1(倒序)
print(newlist) #结果:[4,3]
my_tuple = (1,2,3, 4, 5)
new_tuple =my_tuple[:1:-2] #从头(最后)开始,到下标1(不含)结束,步长-2(倒序)
print(new_tuple) #结果:(5,3)
# 定义集合字面量
{元素, 元素, ..., 元素}
# 定义集合变量
变量名称 = {元素, 元素, ..., 元素}
# 定义空集合
变量名称 = set()
集合.add(元素) | 添加新元素 |
---|---|
集合.remove(元素) | 将指定元素从集合内移除 |
集合.pop() | 从集合中随机取出元素 |
集合.clear() | 清空集合 |
集合1.difference(集合2) | 取出集合1和集合2的差集(1有2无),得到一个新集合。 |
集合1.difference_update(集合2) | 在集合1内,删除和集合2相同的元素。(集合1被修改) |
集合1.union(集合2) | 将集合1和集合2组合成新集合。 |
len(集合) | 统计集合内有多少元素 |
只支持for循环遍历;
集合不支持下标索引,因此不支持while循环。
字典的定义使用{},存储的元素是一个个键值对;
每一个键值对包含Key和Value(用冒号分隔);
键值对之间使用逗号分隔;
Key和Value可以是任意类型(key不可为字典);— 字典可以嵌套
Key不可重复,重复会对原有数据覆盖。
# 定义字典字面量
{key: value, key: value, ..., key: value}
# 定义字典变量
my_dict = {key: value, key: value, ..., key: value}
# 定义空字典
my_dict = {} # 空字典定义方式1
my_dict =dict{} # 空字典定义方式2
字典不可以使用下标索引,但可通过key值检索对应value。
字典[Key] | 获取指定Key对应的Value值 |
---|---|
字典[Key] =Value | 添加或更新键值对 |
字典.pop(Key) | 取出Key对应的Value并在字典内删除此Key的键值对 |
字典.clear() | 清空字典 |
字典.keys() | 获取字典的全部Key,可用于for循环遍历字典 |
len(字典) | 计算字典内的元素数量 |
列表 | 元组 | 字符串 | 集合 | 字典 | |
---|---|---|---|---|---|
元素数量 | 支持多个 | 支持多个 | 支持多个 | 支持多个 | 支持多个 |
元素类型 | 任意 | 任意 | 仅字符 | 任意 | Key: Value(Key:除字典外任意类型 Value:任意类型) |
下标索引 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
重复元素 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
可修改性 | 支持 | 不支持 | 不支持 | 支持 | 支持 |
数据有序 | 是 | 是 | 是 | 否 | 否 |
使用场景 | 可修改、可重复的一批数据 | 不可修改、可重复的一批数据 | 一串字符的记录不可重复的数据 | 不可重复的数据记录场景 | 以Key检索Value的数据记录场景 |
功能 | 描述 |
---|---|
通用for循环 | 遍历容器(字典是遍历key) |
max | 容器内最大元素 |
min() | 容器内最小元素 |
len() | 容器元素个数 |
list() | 转换为列表 |
tuple() | 转换为元组 |
str() | 转换为字符串 |
set() | 转换为集合 |
sorted(序列, [reverse=True]) | 排序,reverse=True表示降序,得到一个排好序的列表 |
字符串进行比较 — 基于数字的ASCII码值大小进行比较
按位比较:一位位进行对比,只要有一位大,那么整体就大。
如字符串"abc"和"abd",由于字符b的ACSII码值大于字符d,因此字符串"abd"大。
又如字符串"a"和"ab",第一位相同,字符"b"比较大,因此字符串"ab"大于字符串"a"。
文本文件 → 编码技术 → 0/1
可用编码:UTF-8/GBK/Big5/…
打开文件→读写文件→关闭文件
操作 | 功能 |
---|---|
f = open(file, mode, encoding) | 打开文件获得文件对象 |
f.read(num) | 读取指定长度字节, 不指定num读取文件全部 |
f.readline() | 读取一行 |
f.readlines() | 读取全部行,得到列表 |
for line in f for lines | for循环文件行,一次循环得到一行数据 |
f.close() | 关闭文件对象 |
with open() as f | 通过withopen语法打开文件,可以自动关闭 |
open(name, mode, encoding):打开已存在的文件,或创建一个新文件
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode:设置打开文件的模式(访问模式):只读、写入、追加等。
encoding:编码格式(推荐使用UTF-8)
f =open('python.txt', 'r', encoding="UTF-8")
# f是open函数的文件对象
# encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
---|---|
w | 打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除;如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,新的内容将会被写入到已有内容之后;如果该文件不存在,创建新文件进行写入。 |
文件对象.read(num):num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。
文件对象.readlines():可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
f = open('python.txt')
content = f.readlines()
# ['hello world\n', 'abcdefg\n', 'aaa\n', 'bbb\n', 'ccc']
print(content)
# 关闭文件
f.close()
文件对象.readline():一次读取一行内容
for line in open("python.txt", "r"):
print(line)
# 每一个line临时变量,就记录了文件的一行数据
f = open("python.txt", "r")
f.close()
# 最后通过close,关闭文件对象,也就是关闭对文件的占用
# 如果不调用close,同时程序没有停止运行,那么这个文件将一直被Python程序占用。
with open("python.txt", "r") as f:
f.readlines()
# 通过在with open的语句块中对文件进行操作
# 可以在操作完成后自动关闭close文件,避免遗忘掉close方法
# 1. 打开文件
f = open('python.txt', 'w')
# 2.文件写入
f.write('hello world')
# 3. 内容刷新
f.flush()
# 1. 打开文件,通过a模式打开即可
f = open('python.txt', 'a')
# 2.文件写入
f.write('hello world')
# 3. 内容刷新
f.flush()
可以使用”\n”来写出换行符
异常(bug):软件出现错误
如果遇到bug:
① 整个程序因为一个BUG停止运行;
② 对BUG进行提醒, 整个程序继续运行。
捕获异常:提前假设某处会出现异常,做好提前准备,当真的出现异常的时候,可以有后续手段。
try:
可能要发生异常的语句
except[异常 as 别名:]
出现异常的准备手段
[else:]
未出现异常时应做的事情
[finally:]
不管出不出现异常都会做的事情
如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。
一般try下方只放一行尝试执行的代码。
try:
print(name)
except NameError as e:
print('变量名未定义错误')
# 捕获所有异常
try:
print(name)
except Exception as e:
print(e)
# 捕获异常并输出描述信息
try:
print(num)
except (NameError, ZeroDivisionError) as e:
print(e)
try:
f = open('test.txt', 'r')
except Exception as e:
f = open('test.txt', 'w')
else:
print('没有异常时执行的代码')
finally:
f.close() # 无论是否异常都执行的代码
异常具有传递性。
当所有函数都没有捕获异常的时候, 程序就会报错。
[from 模块名] import [ 模块 | 类 | 变量 | 函数 | * ] [as 别名]
调用:模块名.功能名()
调用:功能名()
调用:功能名()
⭐ 当导入多个模块,且模块内有同名功能时,调用到的是后面导入的模块的功能。
如果一个模块文件中有__all__
变量,当使用from xxx import *
导入时,只能导入这个列表中的元素。
从物理上看,包就是一个文件夹,包含**__init__.py** 文件和多个模块文件。
从逻辑上看,包的本质依然是模块。
方式一:
import包名.模块名
包名.模块名.目标
方式二:必须在__init__.py文件中添加__all__ = []
,控制允许导入的模块列表。
from包名 import *
模块名.目标
请添加图片描述
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称
class 类名称:
成员变量
def 成员方法(self, 参数列表):
成员方法体
# 创建类对象
对象 = 类名称()
class — 关键字
类的属性 — 即定义在类中的变量(成员变量)
类的行为 — 即定义在类中的函数(成员方法)
self关键字是成员方法定义的时候,必须填写的,用来表示类对象自身。
在方法(类函数)内部,想要访问类的成员变量,必须使用self。
在调用时传参时可以忽略self关键字。
class student:
name = None
ag = None
tel = None
def __init__(self, name, age, tel):
self.name = name
self.age = age
self.tel = tel
print("student类创建了一个对象")
stu = Student("alice", 31,"18500006666")
方法 | 功能 |
---|---|
__init __ | 构造方法,可用于创建类对象的时候设置初始化行为 |
__str__ | 用于实现类对象转字符串的行为 |
__It __ | 用于2个类对象进行小于或大于比较 |
__le __ | 用于2个类对象进行小于等于或大于等于比较 |
__eq __ | 用于2个类对象进行相等比较 |
当类对象需要被转换为字符串之时,会输出内存地址。
可以通过__str__方法,控制类转换为字符串的行为。
class student:
def _init__(self, name, age):
self.name = name
self.age = age
student = Student("alice",11)
print(student) # 结果:<__main__.Studentobjectat0x000002200CFD7040>
print(str(student)) # 结果:<__main__.StudentobjectatOx000002200CFD7040>
class student:
def _init__(self, name, age):
self.name = name
self.age = age
def _str_(self):
return f"student类对象,name={self.name},age={self.age}"
student = Student("alice", 11)
print(student) # 结果:Student类对象,name=alice,age=11
print(str(student)) # 结果:Student类对象,name=alice,age=11
直接对2个对象进行比较是不可以的,但是在类中实现__lt__方法,即可同时完成:小于符号 大于符号 2种比较
方法名:__lt__
返回值:True 或 False
传入参数:other,另一个类对象
内容:自行定义
class student:
def _init__(self, name, age):
self.name = name
self.age = age
def _lt_(self, other):
return self.age < other.age
stu1 = Student("alice",11)
stu2 = Student("bob",13)
print(stu1 < stu2) # 结果:True
print(stu1 > stu2) # 结果:Falue
可用于<=、>=两种比较运算符
方法名:__le__
传入参数:other,另一个类对象
返回值:True 或 False
内容:自行定义
class student:
def _init__(self, name, age):
self.name = name
self.age = age
def _le__(self, other):
return self.age <= other.age
stu1 = Student("alice", 11)
stu2 = Student("bob", 13)
print(stu1 <= stu2) # 结果:True
print(stu1 >= stu2) # 结果:Falue
不实现__eq__方法,对象之间可以比较,但是比较内存地址,也即是:不同对象==比较一定是False结果。
实现了__eq__方法,就可以按照自己的想法来决定2个对象是否相等了。
方法名:__eq__
传入参数:other,另一个类对象
返回值:True 或 False
内容:自行定义
class student:
def __init__(self, name, age):
self.name= name
self.age = age
def _eq__(self, other):
return self.age == other.age
stu1 = Student("alice",11)
stu2 = Student("bob",11)
print(stu1 == stu2) # 结果:True
既然现实事物有不公开的属性和行为,作为现实事物在程序中映射的类也应该支持。
类中提供了私有成员的形式(私有成员变量/私有成员方法)来支持。
定义:
私有成员变量:变量名以__开头(2个下划线)
私有成员方法:方法名以__开头(2个下划线)
class Phone:
IMEI = None # 序列号
producer = None # 厂商
__current_voltage = None # 当前电压,私有成员变量
def call_by_5g(self):
print("5g通话已开启")
def __keep_single_core(self): # 私有成员方法
print("让CPU以单核模式运行以节省电量")
⭐ 私有方法无法直接被类对象使用(不对外开放),但可以被其他成员使用;私有变量无法赋值,也无法获取值。
单继承:将从父类那里继承(复制)来成员变量和成员方法(不含私有)
class 类名(父类名):
类内容体
多继承:一个类可以继承多个父类
class 类名(父类1, 父类2, ..., 父类N):
类内容体
多个父类中,如果有同名的成员,那么默认以继承顺序(从左到右)为优先级。
即:先继承的保留,后继承的被覆盖
复写:在子类中重新定义同名的属性或方法即可。
class Phone:
IMEI = None#序列号
producer = "ITCAsT"#厂商
def call_by_5g(self):
print("父类的5g通话")
class MyPhone(Phone) :
proucer = "ITHEIMA"#复写父类属性
def call_by_5g(self):#复写父类方法
print("子类的5g通话")
一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员;
如果需要使用被复写的父类的成员,需要特殊的调用方式:
方式1:调用父类成员
使用成员变量:父类名.成员变量
使用成员方法:父类名.成员方法(self)
方式2:使用super()调用父类成员
使用成员变量:super().成员变量
使用成员方法:super().成员方法()
类型注解:在代码中涉及数据交互的地方,提供数据类型的注解(显式的说明)。
主要功能:
变量: 类型
或在注释中进行:# type: 类型
元组类型设置类型详细注解,需要将每一个元素都标记出来
字典类型设置类型详细注解,需要2个类型,第一个是key,第二个是value。
一般无法直接看出变量类型时,会添加变量的类型注解。
类型注解仅仅是提示性的,不是决定性的。
def 函数方法名(形参名: 类型, 形参名: 类型, ...) -> 返回值类型 :
Union联合类型注解,在变量注解、函数(方法)形参和返回值注解中,均可使用。
my_list: list[union(int, str)] = [1, 2, 'itcast', "itheima"]
my_dict: dict[str, Union[str, int]] = {"name":"alice", "age": 31}
def func(data: Union[int, str]) -> Union[int, str]:
pass
多态:多种状态,即完成某个行为时,使用不同的对象会得到不同的状态。
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
print("汪汪汪")
class Cat(Animal):
def speak(self):
print("喵喵喵")
多态常作用在继承关系上,如:函数(方法)形参声明接收父类对象,实际传入父类的子类对象进行工作。
父类用来确定有哪些方法,具体的方法实现由子类自行决定。 — 抽象类
抽象类:含有抽象方法的类称之为抽象类
抽象方法:方法体是空实现的(pass)称之为抽象方法
在函数嵌套的前提下,内部函数使用了外部函数的变量,并且外部函数返回了内部函数,把这个使用外部函数变量的内部函数称为闭包。
左图中,通过全局变量记录余额,有被修改的风险。
def outer(num1): # 外部函数
def inner(num2): # 内部函数
nonlocal num1
num1 += num2
print(num1)
return inner # 返回内部函数
使用nonlocal关键字修饰外部函数的变量才可在内部函数中修改它
装饰器其实也是一种闭包, 其功能就是在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能。
def outer(func):
def inner():
print("我要睡觉了")
func ()
print("我起床了")
return inner
def sleep():
import random
import time
print("睡眠中...")
time.sleep(random.randint(1, 5))
outer(sleep)() # 调用
使用@outer定义在目标函数sleep之上
@outer
def sleep():
import random
import time
print("睡眠中")
time.sleep(random.randint(1, 5))
创建类的实例后,得到的是完全独立的两个对象,内存地址并不相同。
class Tool:
pass
t1 = Tool()
t2 = Tool()
print(t1)
print(t2)
某些场景要求,无论获取多少次类对象,都仅提供一个具体的实例,以节省创建类对象的开销和内存开销。
单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点。
实现模型:在一个文件中定义 → 在另一个文件中导入对象 → 二者对象地址相同,实际为一个对象。
class StrTools:
pass
str_tool = StrTools()
from test import str_tool
s1 = str_tool
s2 = str_tool
print(s1) # <test.StrToolsobjectat0X0000013D001DB910>
print(s2) # <test.StrToolsobjectat0X0000013D001DB910>
当需要大量创建一个类的实例的时候, 可以使用工厂模式。
即从原生的使用类的构造去创建对象的形式迁移到基于工厂提供的方法去创建对象的形式。
class Factory:
def get_person(self, p_type):
if p-type = 'w':
return Worker()
elif p_type ='s':
return Student()
else:
return Teacher()
factory = Factory()
worker = factory.get_person('w')
stu = factory.get_person('s')
teacher = factory.get_person('t')
上图使用工厂类的get_person()方法去创建具体的类对象
优点:
操作系统中可以运行多个进程,即多任务运行
一个进程内可以运行多个线程,即多线程运行
并行执行:同一时间做不同的工作。
进程之间就是并行执行的,操作系统可以同时运行好多程序,这些程序都是在并行执行。除了进程外,线程其实也是可以并行执行的。 — 多线程并行执行
Python的多线程可以通过threading模块来实现。
import threading
thread_obj = threading.Thread([group [, target [, name [, args [, kwargs]]]]])
# group:暂时无用,未来功能的预留参数
# target:执行的目标任务名
# args:以元组的方式给执行任务传参
# kwargs:以字典方式给执行任务传参
# name:线程名,一般不用设置
启动线程:thread_obj.start()
def sing():
while True:
print("我在唱歌,啦啦啦。.。")
time.sleep(1)
def dance():
while True:
print("我在跳舞,哗哗哗哗哗")
time.sleep(1)
# 多线程运行模式
sing_thread = threading.Thread(target = sing)
dance_thread = threading.Thread(target = dance)
sing_thread.start()
dance_thread.startO)
socket (简称套接字) 是进程之间通信一个工具,负责进程之间的网络数据传输,好比数据的搬运工。
Socket服务端:等待其它进程的连接、可接受发来的消息、可以回复消息
Socket客户端:主动连接服务端、可以发送消息、可以接收回复
# 1.创建socket对象 import socket socket_server = socket.socket() # 2.绑定socketserver到指定IP和地址 socket_server.bind(host,port) # 3.服务端开始监听端口 socker_server.listen(backlog) # back1og为int整数,表示允许的连接数量,超出的会等待 # 可以不填,不填会自动设置一个合理值 # 4.接收客户端连接,获得连接对象 conn,address = socket_server.accept() print(f"接收到客户端连接,连接来自:{address}") # accept方法是阻塞方法,如果没有连接,会卡再当前这一行不向下执行代码 # accept返回的是一个二元元组,可以使用上述形式,用两个变量接收二元元组的2个元素 # 5.客户端连接后,通过recv方法,接收客户端发送的消息 while True: data = conn.recv(1024).decode("uTF-8") # recv方法的返回值是字节数组(Bytes),可以通过decode使用uTF-8解码为字符串 # recv方法的传参是buffsize,缓冲区大小,一般设置为1024即可 if data =='exit': break print("接收到发送来的数据:",data) # 可以通过while True无限循环来持续和客户端进行数据交互 # 可以通过判定客户端发来的特殊标记,如exit,来退出无限循环 # 6.通过conn(客户端当次连接对象),调用send方法可以回复消息 while True: data = conn.recv(1024).decode("uTF-8") if data =='exit': break print("接收到发送来的数据:",data) conn.send("你好".encode(UTF-8")) # 7.conn(客户端当次连接对象)和socketserver对象调用close方法,关闭连接 conn.close()
# 1.创建socket对象 import socket socket_client = socket.socket() # 2.连接到服务端 socket_client.connect(("localhost",8888)) # 3.发送消息 while True:#可以通过无限循环来确保持续的发送消息给服务端 send_msg=input("请输入要发送的消息") if send_msg='exit': #通过特殊标记来确保可以退出无限循环 break socket_client.send(send_msg.encode("UTF-8")) #消息需要编码为字节数组(UTF-8编码) #4.接收返回消息 whileTrue: send_msg=input("请输入要发送的消息").encode("UTF-8") socket_client.send(send_msg) recv_data =socket_client.recv(1024)#1024是缓冲区大小,一般1024即可 #recv方法是阻塞式的,即不接收到返回,就卡在这里等待 print("服务端回复消息为:“,recv_data.decode("UTF-8"))#接受的消息需要通过UTF-8解码为字符串 # 5.关闭链接 socket_client.close()#最后通过close关闭链接
正则表达式(规则表达式,Regular Expression):使用单个字符串来描述、匹配某个句法规则的字符串,常被用来检索、替换那些符合某个模式(规则)的文本。
字符串定义规则,并通过规则去验证字符串是否匹配。
re.match(匹配规则, 被匹配字符串):从被匹配字符串开头进行匹配, 匹配成功返回匹配对象(包含匹配的信息),匹配不成功返回空。
S = 'python itheima python itheima python itheima'
result = re.match('python', s)
print(result) # <re.Matchobject; span=(0, 6),match='python'>
print(result.span()) # (0, 6)
print(result.group()) # python
search(匹配规则, 被匹配字符串):搜索整个字符串,找出匹配的。从前向后,找到第一个后,就停止,不会继续向后。
S = '1python666itheima666python666'
result = re.search('python', s)
print(result) # <re.Matchobject;span=(1, 7),match='python'>
print(result.span()) # (1, 7)
print(result.group()) # python
findall(匹配规则, 被匹配字符串):匹配整个字符串,找出全部匹配项;找不到返回空list: []
S = '1python666itheima666python666'
result = re.findall('python', s)
print(result) # ['python', 'python']
字符 | 功能 |
---|---|
. | 匹配任意一个字符(除了\n),、\.匹配点本身 |
[] | 匹配[]中列举的字符 |
\d | 匹配数字,即0-9 |
\D | 匹配非数字 |
\s | 匹配空白,即空格、Tab键 |
\S | 匹配非空白 |
\w | 匹配单词字符,即a-z、A-Z、0-9、_ |
\W | 匹配非单词字符 |
字符 | 功能 |
---|---|
* | 匹配前一个规则的字符出现0至无数次 |
+ | 匹配前一个规则的字符出现1至无数次 |
? | 匹配前一个规则的字符出现0次或1次 |
{m} | 匹配前一个规则的字符出现m次 |
{m,} | 匹配前一个规则的字符出现最少m次 |
{m,n} | 匹配前一个规则的字符出现m次至n次 |
字符 | 功能 |
---|---|
| | 匹配左右任意一个表达式 |
() | 将括号中字符作为一个分组 |
字符 | 功能 |
---|---|
^ | |
$ | 匹配字符串结尾 |
\b | 匹配一个单词的边界 |
\B | 匹配非单词边界 |
案例:
^\[0-9a-zA-Z]{6, 10}\$
;^\[1-9]\[0-9]{4,10}
,[1-9]匹配第一位,[0-9]匹配后面4到10位;^\[\w-]+(\\.\[\w-]+)\*@(qq|163|gmail)(\\.\[\w-]+)+&
。递归: 即方法(函数)自己调用自己的一种特殊编程写法
def func():
if ...:
func()
return ...
场景:在D:/test 文件夹内,有如下嵌套结构和所属的文件, 可以通过递归编程的形式完成。
⭐ 需要注意:
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。