前言前的前言:奇怪,为什么会有人看(゚Д゚;),推送机制诱导的吗
前言:现在(2024.1.17)以B站课程杨淑娟老师的课程学习,菜鸟一枚,万望指导
一、Python基本概念与应用场景
1.Python基本概念:①Python是一门高级语言,经编译器编译之后变为机器语言才可执行 (Python是脚本语言); ②Python是一门解释型语言,需要将源代码逐条转换成目标代码,同时逐条运行目标代码,执行解释的计算机程序也称为解释器;③Python特点:明确简单而优雅,库丰富而多样。
2.Python应用领域:①web开发;②数据分析与科学计算;③人工智能与机器学习(常用TensorFlow,Keras,PyTorch);④自动化测试与运维;⑤网络爬虫(request);⑥游戏开发!
目前学习工具与平台:pycharm3.8 python3.10
二、Python基本编程思维
基本的程序编写流程:IPO程序编写方法
三、Python基础语法
1.input函数:变量名 = input('提示文字') 注意事项:input获取的数据返回为字符串类型
2.注释:单行注释加前缀#,多行注释使用''' '''
3.代码缩进:每行语句开始前的空白区域,因为Python语法较为简洁,没有c语言或者JS一样的多个嵌套的括号,因此嵌套关系常看缩进,需要严格的缩进。(pycharm的提示选项内有格式化选项)
4.print函数:
print(内容)
其完整版其实是
print(内容,...,sep='内容间分隔方式',end='尾部内容',file=写入位置) 注意事项:字符要加引号,变量等不用
5.文件打开与写入:
fp = open('text.txt', 'w')
#其中的w指的是插入形式(write)
print(chr(28145), file=fp)
6.关键字(保留字):在Python中被赋予特定定义的一些单词,不可作为变量名与对象名等使用,以下为基本的保留字
and | as | assert | break | class | continue | def |
del | elif | else | except | finally | for | from |
False | global | if | import | in | is | lambda |
nonlocal | not | None | or | pass | raise | return |
try | True | while | with | yield | await | async |
7.Python标识符命名规则与规范:
①可用中英文,下划线,数字;②第一个不能是数字;③不用关键字;④严格区分大小写;⑤下划线开头的具有特殊意义;
①全部小写的短小单词,以下划线分隔;②包名尽量短小,以点分割;③模块内部类:下划线+Pascal命名法,如MyClass内部的_InnerMyClass;
④函数,类的属性和方法的命名,一般全用小写字母,多个单词之间以下划线分隔⑤常量一般全用大写,下划线分隔;
⑥以单下划线开头的模块变量与函数受保护,在使用“from xxx import *”语句从模块中导入时,这些模块变量或函数不能被导入;⑦双下划线开头慎用,是类私有的;⑧头尾双下划线是Python专用标识,勿使用此型
8.变量与常量
变量的语法结构: 除了一般的数据结构之外还可赋值为一个方法返回的参数
变量名 = value
常量的语法结构:与变量无异,但是命名规则要注意,而且一般直接赋值
9.数值类型
①整数类型:没有小数部分的数值,包含正整数、负整数和0
注:Python中不同进制之前需要引导符号以用于被辨识。十进制无前缀,二进制以0b或0B作为前缀,八进制以0o或者0O作为前缀,十六进制以0x或者0X作为前缀
②浮点数类型:表示带有小数点的数值,计算时注意浮点误差
复数:Python中的复数与数学中形式一致,实数部分以.real表示,虚数部分以.imag表示
# 实部与虚部
x = 123 + 456j
print(x)
print(x.real)
print(x.imag)
10.字符串类型与操作
①普通字符串,可以表示计算机所能识别的一切字符
②界定符:单引号,双引号,三引号
③转义字符:\+字母或符号,具体查表
④原字符:字符串界定符前加r或者R,使转义字符失效变为普通字符
⑤索引:有序的字符序列(字符串)中,某个字符的检索号称为索引(正序从0开始,逆序从-1开始)
⑥切片:对字符串中某个子串或者区间的检索,基本语法结构如下(左闭右开):
#字符串切片
s = 'hello world'
print(s[0])
print(s[-2])#反向
print('hello world'[2:5:3])#2到5,跨步为3
print(s[:5])#从零开始到第五个
⑦字符串操作:拼接x+y 复制n次x*n 检索x是否为s的子串,返回布尔值x in s
11.布尔类型:True表示1,False表示0(反之,在进行判断时除了0以外其他都视为True)false情况:False或者None,各种数值中的0,空序列,自定义对象的实例,该对象的__bool__()方法返回False或__len__()方法返回0
12.数据类型之间的转换:
①隐式转换:在函数运算以及程序运行过程中内置函数导致的转换(可能类似于JS?有待学习)
②显式转换:使用转换函数转换数据类型
函数 | 描述说明 |
int(x) | 将x转换为整数类型 |
float(x) | 将x转换为浮点数类型 |
str(x) | 将x转成字符串 |
chr(x) | 将整数 x转换为一个字符 |
ord(x) | 将一个字符x转换为其对应的整数值 |
hex(x) | 将一个整数 x转换为一个十六进制字符串 |
oct(x) | 将一个整数 x转换为一个八进制字符串 |
bin(x) | 将一个整数 x转换为一个二进制字符串 |
13.eval函数:python中的内置函数,去掉语句最外侧的引号后执行该语句(注意,该语法格式为 :变量名=eval(字符串)与其他函数共用时注意格式与嵌套关系)
num = eval(input('输入算式'))
print('千位为', num // 1000)
print('百位为', num % 1000 // 100)
print('十位为', num % 100 // 10)
print('个位为', num % 10 // 1)
14.算术运算符:处理四则运算,优先级为:** 其次 *,/,%,// 其次 -,+ ,具体如下:
运算符 | 描述说明 | 示例 | 结果 |
+ | 加法 | 1+1 | 2 |
- | 减法 | 1-1 | 0 |
* | 乘法 | 2*3 | 6 |
/ | 除法 | 10/2 | 5.0 |
// | 整除 | 10//3 | 3 |
% | 取余 | 10%3 | 1 |
** | 幂运算 | 2**4 | 16 |
15.赋值运算符 :故名思议,具体如下:
运算符 | 描述说明 | 示例 | 展开形式 |
= | 简单的赋值运算 | x=y | x=y |
+= | 加赋值 | x+=y | x=x+y |
-= | 减赋值 | x-=y | x=x-y |
*= | 乘赋值 | x*=y | x=x*y |
/= | 除赋值 | x/=y | x=x/y |
%= | 取余赋值 | x%=y | x=x%y |
**= | 幂赋值 | x**=y | x=x**y |
//= | 整除赋值 | x//=y | x=x//y |
16.比较运算符,依旧看图:
运算符 | 描述说明 | 示例 | 展开形式 |
> | 大于 | 98>90 | True |
< | 小于 | 98<90 | False |
== | 等于 | 98==90 | False |
!= | 不等于 | 98!=90 | True |
>= | 大于或等于 | 98>=98 | True |
<= | 小于或等于 | 98<=98 | True |
17. 逻辑运算符,与或非三巨头,具体如下:
&&与:都真为真
||或:一真即真
!非:真假互换
运算符 | 描述说明 | 用法 | 结合方向 |
and | 逻辑与 | 表达式1 and 表达式2 | 从左到右 |
or | 逻辑或 | 表达式1 or 表达式2 | 从左到右 |
not | 逻辑非 | not 表达式 | 从右到左 |
18. 位运算符,将数字看做二进制进行计算与操作。首先以“位与”举例:当两数对应位置都为一时结果为一,否则为零,其他运算符也都如此运算一般,是“按位”进行运算。
①位与(&):对两个操作数的每个对应位执行逻辑与操作,只有当两个位都为 1 时,结果才为 1,否则为 0。
②位或(|):对两个操作数的每个对应位执行逻辑或操作,只有当两个位都为 0 时,结果才为 0,否则为 1。
③位异或(^):对两个操作数的每个对应位执行逻辑异或操作,当两个位不同时,结果为 1,否则为 0。
④位取反(~):对操作数的每个位执行逻辑非操作,将每个位取反。
⑤左移(<<):将操作数的二进制表示向左移动指定的位数,并在右侧用零填充。
⑥右移(>>):将操作数的二进制表示向右移动指定的位数,并在左侧用符号位填充(对于正数是 0,对于负数是 1 注意:填充时空出的位置全部都是填符号位)。
注意:在使用位运算符时,操作数会被转换为整数进行计算。
下为举例,内部过程自己写一手二进制数即可:
#位与
a = 5 # 二进制表示为 0101
b = 3 # 二进制表示为 0011
result = a & b
print(result) # 输出 1,即二进制的 0001
#位或
a = 5 # 二进制表示为 0101
b = 3 # 二进制表示为 0011
result = a | b
print(result) # 输出 7,即二进制的 0111
#位异或
a = 5 # 二进制表示为 0101
b = 3 # 二进制表示为 0011
result = a ^ b
print(result) # 输出 6,即二进制的 0110
#位取反
a = 5 # 二进制表示为 0101
result = ~a
print(result) # 输出 -6,即二进制的 -0110
#左移
a = 5 # 二进制表示为 0101
result = a << 2
print(result) # 输出 20,即二进制的 10100
#右移
a = 5 # 二进制表示为 0101
result = a >> 2
print(result) # 输出 1,即二进制的 0001
14-18运算符优先级:
①** ②~、+、- ③*、/、%、// ④+、- ⑤<<、>> ⑥& ⑦^ ⑧| ⑨<、<=、>、>=、!=、== 若有赋值运算符则优先级最低(最后运行)
四、Python中的流程控制与基本的控制
1、程序的组织结构:顺序结构、循环结构、分支(选择)结构
2、if else elif 分支结构语法 。注意:一般else用于最后,指不符合所有情况
num = int(input("请输入一个数字:"))
if num > 0:
print("这个数字是正数")
elif num < 0:
print("这个数字是负数")
else:
print("这个数字是零")
3、for 与 for else 循环结构语法。其中for else一般用于查找
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
-------------------------------------------------
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
if fruit == "orange":
print("找到了橙子")
break
else:
print("没有找到橙子")
4.while 循环结构语法
limit = 10
number = 1
while number <= limit:
square = number ** 2
print(square)
number += 1
5.for in循环结构
size = 5
# 上半部分
for i in range(1, size+1):
print(" " * (size-i) + "*" * (2*i-1))
# 下半部分
for i in range(size-1, 0, -1):
print(" " * (size-i) + "*" * (2*i-1))
#range(start起始值,stop结束值(不包括该值),step步长)
6.程序跳转语句
①break 跳出整个循环结构
②continue 跳出当前这个循环
7.空语句pass,类似于占位符,只是为了语法正确,无意义
五、组合数据类型
索引:本章主要了解序列,索引,序列,列表,元组,字典,集合的概念与其相关操作
序列是一个用于存储多个值的连续空间,每个值都对应一个整数的编号,此编号称为索引。
索引分为正向递增索引(0 至 N-1)与反向递减索引(-1 至-N)
切片操作语法结构:序列名[start:end(不包含该值):step] 返回一个与原始序列类型相同的序列
序列的操作:
操作符/函数 | 描述说明 |
x in s | 如果x是s的元素,结果为True,否则结果为False |
x not in s | 如果x不是s的元素,结果为True,否则结果为False |
len(s) | 序列s中元素的个数(即序列的长度) |
max(s) | 序列s中元素的最大值 |
min(s) | 序列s中元素的最小值 |
s.index(x) | 序列s中第一次出现元素x的位置 |
s.count(x) | 序列s中出现x的总次数 |
删除操作:del 序列名
遍历操作:enumerate函数,如:
for index ,item in enumerate(lst):
输出index和item
序列类型:
①列表类型:由一系列的按特定顺序排列的元素组成,是Python中内置的可变序列,使用[]定义列表或使用内置函数 list() 创建列表,使用逗号分隔,列表内元素可以是任意的数据类型
列表的方法 | 描述说明 |
lst.append(x) | 在列表lst最后增加一个元素 |
lst.insert(index,x) | 在列表中第index位置增加一个元素 |
lst.clear() | 清除列表lst中所有元素 |
lst.pop(index) | 将列表lst中第index位置的元素取出,并从列表中将其删除 |
lst.remove(x) | 将列表lst中出现的第一个元素x删除 |
lst.reverse(x) | 将列表lst中的元素反转 |
lst.copy() | 拷贝列表lst中的所有元素,生成一个新的列表 |
列表对象排序:sort方法: 列表名.sort(key = 排序方法,reverse = 排序方式)
内置函数sorted: sorted(排序对象,key = 排序方法,reverse = 排序方式)
列表生成语法结构:lst=[expression for item in range] 或lst=[expression for item in range(n)]。其中expression为表达式,range可为一个对象,此方法将从目标对象中取符合表达式的数据取出作为列表
②元组类型:是Python中内置的不可变有序序列,使用()定义或元组名=tuple(序列)方法定义,以逗号分隔(当元组中仅有一个元素时逗号也要)其中元组生成式的结果是一个生成器对象,需要转变方可见,或者使用__next__()方法进行提取(提取完了原来的元组就空了)。
新定义标明与对比:
元组 | 列表 |
不可变序列 | 可变序列 |
无法实现添加、删除和修改元素等操作 | append()、insert()、remove()、pop()等方法实现添加和删除列表元素 |
支持切片访问元素,不支持修改操作 | 支持切片访问和修改列表中的元素 |
访问和处理速度快 | 访问和处理速度慢 |
可以作为字典的键 | 不能作为字典的键 |
列表的方法列表的方。其中
③字典类型:由多个键(key)值(value)对构成,他表示索引所使用的键和对应的值构成的成对关系,可使用{}直接创建或者使用映射函数和构造函数构建:zip(key序列,value序列) dict(key=value,...)
字典中的key是无序的,取值时使用d[key]或者d.get[key]取对应值,或者遍历
for key, value in my_dict.items():
print(key, "->", value)
for element in d.items():
key, value = element
print(key, "->", value)
字典相关操作:
字典的方法 | 描述说明 |
d.keys() | 获取所有的key数据 |
d.values() | 获取所有的value数据 |
d.pop(key,default) | key存在获取相应的value,同时删除key-value对,否则获取默认值 |
d.popitem() | 随机从字典中取出一个key-value对,结果为元组类型,同时将该key-value从字典中删除 |
d.clear() | 清空字典中所有的key-value对 |
④集合类型:与数学中集合的概念一致,是一个无序不重复的元素序列(可用于去重),使用{}定义,以逗号分隔,集合是可变数据类型,但是只能存储不可变数据类型(比如他能存一个元组进去或者删去一个元素,但是不能存储字典和列表)
内置函数set()创建集合:集合名 = set(可迭代对象)
集合操作:①取交集 A&B;②取并集 A|B; ③取差集 A-B(注意,这里是在A中去掉与B重合部分); ④取补集 A^B集合的方集合的方法
集合的方法 | 描述说明 |
s.add(x) | 如果x不在集合s中,则将x添加到集合s |
s.remove(x) | 如果x在集合中,将其删除,如果不在集合中,程序报错 |
s.clear() | 清除集合中所有元素 |
Python3.11新特性:结构模型匹配 字典合并运算符| 同步迭代
#结构模型匹配,case后可以跟随各种模式
point = (2, 3)
match point:
case (0, 0):
print("原点")
case (x, 0):
print(f"在 x 轴上,x 坐标为 {x}")
case (0, y):
print(f"在 y 轴上,y 坐标为 {y}")
case (x, y):
print(f"在坐标 ({x}, {y})")
#字典合并运算符
dict1 = {"a": 1, "b": 2}
dict2 = {"b": 3, "c": 4}
merged_dict = dict1 | dict2
print(merged_dict) # 输出 {"a": 1, "b": 3, "c": 4}
#同步迭代
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name} is {age} years old")
#将输出相同位置处的元素
#Alice is 25 years old
#Bob is 30 years old
#Charlie is 35 years old
六、字符串与正则表达式
字符串是Python中的不可变数据类型,对他的修改实际上是“替换”,以下为课件中给出的字符串基本操作
方法名 | 描述说明 |
str.lower() | 将str字符串全部转成小写字母,结果为一个新的字符串 |
str.upper() | 将str字符串全部转成大写字母,结果为一个新的字符串 |
str.split(sep=None) | 把str按照指定的分隔符sep进行分隔,结果为列表类型 |
str.count(sub) | 结果为sub这个字符串在str中出现的次数 |
str.find(sub) | 查询sub这个字符串在str中是否存在,如果不存在结果为-1,如果存在,结果为sub首次出现的索引 |
str.index(sub) | 功能与find()相同,区别在于要查询的子串sub不存在时,程序报错 |
str.startswith(s) | 查询字符串str是否以子串s开头 |
str.endswith(s) | 查询字符串str是否以子串s结尾 |
str.replace(old,news) | 使用news替换字符串s中所有的old字符串,结果是一个新的字符串 |
str.center(width,fillchar) | 字符串str在指定的宽度范围内居中,可以使用fillchar进行填充 |
str.join(iter) | 在iter中的每个元素的后面都增加一个新的字符串str |
str.strip(chars) | 从字符串中去掉左侧和右侧chars中列出的字符串 |
str.lstrip(chars) | 从字符串中去掉左侧chars中列出的字符串 |
str.rstrip(chars) | 从字符串中去掉右侧chars中列出的字符串 |
格式化字符串:①使用占位符;②使用f-string方法;③使用str.format()方法
#占位符方式
name = "Alice"
age = 25
# 使用 %s、%d、%f 占位符进行格式化
message = "My name is %s and I am %d years old. My height is %.2f meters." % (name, age, 1.65)
print(message)
#结果为:My name is Alice and I am 25 years old. My height is 1.65 meters.
#使用f-string
name = "Bob"
age = 30
# 使用 f-string 进行格式化
message = f"My name is {name} and I am {age} years old. My height is {1.75:.2f} meters."
print(message)
#结果为:My name is Bob and I am 30 years old. My height is 1.75 meters.
#使用str.format()
name = "Charlie"
age = 35
# 使用 str.format() 进行格式化
message = "My name is {} and I am {} years old. My height is {:.2f}meters.".format(name,age, 1.80)
print(message)
#结果为:My name is Charlie and I am 35 years old. My height is 1.80 meters.
其中,格式化字符串的详细格式由{}中的要求决定,要求语法大致为:①:作为引导符号;②<>^作为对齐方式;③数字作为宽度;④逗号作为数字的千位分隔符;⑤ . + 数字 作为数据精度;⑥整数类型与浮点数类型的代号
字符串的编解码:在网络传输中,内存数据先从本地的字符串(string)编码为二进制进行传输,到达目标地址后再由接收方解码为字符串
Python中的字符串编解码方式:使用encode()编码,使用decode()解码。完整格式实例如下:
#encoded_string = original_string.encode(encoding=#, errors=#)
#其中encoding为编码标准(如UTF-8),errors为编码错误时的处理方式
s = "hello"
encoded_string = s.encode('utf-8')
print(encoded_string)
#decoded_string = encoded_string.decode(encoding=#, errors=#)
#参数意义同上
b = b'hello'
decoded_string = b.decode('utf-8')
print(decoded_string)
数据验证与正则表达式
1.数据验证方法
方法名 | 描述说明 |
str.isdigit() | 所有字符都是数字(阿拉伯数字) |
str. isnumeric() | 所有字符都是数字 |
str. isalpha() | 所有字符都是字母(包含中文字符) |
str.isalnum() | 所有字符都是数字或字母(包含中文字符) |
str.islower() | 所有字符都是小写 |
str.isupper() | 所有字符都是大写 |
str.istitle() | 所有字符都是首字母大写 |
str.isspace() | 所有字符都是空白字符(\n、\t等) |
字符串拼接:①使用str.join()方法;②直接使用+号拼接;③使用格式化字符串进行拼接;④通过集合的去重性质进行去重拼接
2.正则表达式 (使用时需要导入re模块)
正则匹配流程:定义模式字符串——选定被匹配对象——选定匹配方式进行匹配——接收匹配结果
import re
def validate_phone_number(phone_number):
pattern = r'^\(?(\d{3})\)?[-.\s]?(\d{3})[-.\s]?(\d{4})$'
match_result = re.match(pattern, phone_number)
if match_result:
area_code = match_result.group(1)
prefix = match_result.group(2)
line_number = match_result.group(3)
print(f"Valid US phone number: ({area_code}) {prefix}-{line_number}")
else:
print("Invalid US phone number")
# 测试例子
validate_phone_number('123-456-7890') # Invalid US phone number
validate_phone_number('(123) 456-7890') # Valid US phone number: (123) 456-7890
validate_phone_number('555.123.4567') # Invalid US phone number
①模式字符串:由元字符,限定符与自定义的匹配规则构成的字符串,用于做正则匹配时的规则;
元字符 | 描述说明 | 举例 | 结果 |
. | 匹配任意字符(除\n) | ’p\nytho\tn’ | p、y、t、h、o、\t、n |
\w | 匹配字母、数字、下划线 | ‘python\n123’ | p、y、t、h、o、n、1、2、3 |
\W | 匹配非字母、数字、下划线 | ‘python\n123’ | \n |
\s | 匹配任意空白字符 | ‘python\t123’ | \t |
\S | 匹配任意非空白字符 | ‘python\t123’ | p、y、t、h、o、n、1、2、3 |
\d | 匹配任意十进制数 | ‘python\t123’ | 1、2、3 |
限定符 | 描述说明 | 举例 | 结果 |
? | 匹配前面的字符0次或1次 | colou?r | 可以匹配color或colour |
+ | 匹配前面的字符1次或多次 | colou+r | 可以匹配colour或colouu...r |
* | 匹配前面的字符0次或多次 | colou*r | 可以匹配color或colouu....r |
{n} | 匹配前面的字符n次 | colou{2}r | 可以匹配colouur |
{n,} | 匹配前面的字符最少n次 | colou{2,}r | 可以匹配colouur或colouuu...r |
{n,m} | 匹配前面的字符最小n次,最多m次 | colou{2,4}r | 可以匹配colouur或colouuur或colouuuur |
其它字符 | 描述说明 | 举例 | 结果 |
区间字符[] | 匹配[]中所指定的字符 | [.?!] [0-9] | 匹配标点符号点、问号,感叹号 匹配0、1、2、3、4、5、6、7、8、9 |
排除字符^ | 匹配不在[]中指定的字符 | [^0-9] | 匹配除0、1、2、3、4、5、6、7、8、9的字符 |
选择字符| | 用于匹配|左右的任意字符 | \d{18}|\d{15} | 匹配15位身份证或18位身份证 |
转义字符 | 同Python中的转义字符 | \. | 将.作为普通字符使用 |
[\u4e00-\u9fa5] | 匹配任意一个汉字 | ||
分组() | 改变限定符的作用 | six|fourth (six|four)th | 匹配six或fourth 匹配sixth或fourth |
②re模块:Python中的内置模块,使用不同函数以进行不同规则的匹配
函数 | 功能描述 |
re.match(pattern,string,flags=0) | 用于从字符串的开始位置进行匹配,如果起始位置匹配成功,结果为Match对象,否则结果为None。 |
re.search(pattern,string,flags=0) | 用于在整个字符串中搜索第一个匹配的值,如果匹配成功,结果为Match对象,否则结果为None。 |
re.findall(pattern,string,flags=0) | 用于在整个字符串搜索所有符合正则表达式的值,结果是一个列表类型。 |
re.sub (pattern,repl,string,count,flags=0) | 用于实现对字符串中指定子串的替换 |
re.split(pattern,string,maxsplit,flags=0) | 字符串中的split()方法功能相同,都是分隔字符串 |
七、异常处理
1.try语句,用于可能出现异常的地方,编译器内运行时的报错实际上可以看做else语句运行了的结果
try:
# 可能会出现异常的代码块
except ExceptionType as e:
# 异常处理代码
else:
# 如果没有异常发生时执行的代码
finally:
# 无论是否有异常都会执行的清理代码
2.raise语句抛出异常,在必要时,可以在适当的条件下使用 raise
来主动触发异常,从而进行异常处理。
raise Exception("An error occurred")
八、函数定义与调用
1.函数分类:内置函数与自定义函数
自定义函数:def 函数名(参数列表):函数体 [返回值列表]
def add_numbers(num1, num2):
"""计算两个数的和"""
sum = num1 + num2
return sum # 返回和
# 测试函数
result = add_numbers(4, 6)
print("4 + 6 =", result) # 输出:4 + 6 = 10
2.形参与实参
- 形参是函数定义时声明的变量,用于接收实参的值。
- 实参是函数调用时提供给函数的具体数值或变量。
- 在函数调用过程中,实参被传递给对应的形参,函数内部使用形参来执行相应的操作。
函数的参数传递
- 位置参数:调用时的参数个数和顺序必须与定义时相同。
- 关键字参数:使用“形参名称 = 值”且符合格式即可,顺序可以不同。
- 默认值参数:在函数定义时对形参进行赋值,调用时如果不传入形参则使用该默认值。
- 个数可变的位置参数:参数名称前加*,使用时将把位置参数置于一个元组中。
- 个数可变的关键字参数:参数名前加**,使用时将把关键字参数置于一个字典中。
- 返回值参数:运行结果使用 return 返回值 他可以出现在函数中任一位置,将返回结果并结束参数,若返回时有多个则为元组类型。
-
#默认值参数演示 def greet(name, greeting="Hello"): # 这里连续赋值,一般不建议这样 """打印问候语""" print(greeting + ", " + name + "!") # 调用函数,并传递一个参数 greet("Alice") # 输出:Hello, Alice! # 调用函数,并传递两个参数 greet("Bob", "Hi") # 输出:Hi, Bob! #个数可变的位置参数举例,参数前面加* def sum_numbers(*args): """计算所有数的和""" sum = 0 for num in args: sum += num return sum # 调用函数,并传递多个参数 result = sum_numbers(1, 2, 3, 4, 5) print(result) # 输出:15 #个数可变的关键字参数举例,参数前面加** def show_info(**kwargs): """显示个人信息""" for key, value in kwargs.items(): print(key + ": " + value) # 调用函数,并传递多个键值对参数 show_info(name="Alice", age="25", city="New York")
3.变量作用域:①局部变量:在函数定义处的参数和函数内部定义的变量,仅在函数内部作用;
②全局变量:在函数外或使用global关键字修饰的变量,在整个程序内作用。
4.匿名函数lambda:语法为:函数名 = lambda 参数列表:函数体 即没有名字(这里面的“函数名”其实是一个变量)的函数,一般即写即用,只能使用一次。
# 定义一个匿名函数,计算两个数的和
sum = lambda x, y: x + y #这里是把lambda匿名函数的值传给sum这个变量
# 调用匿名函数
result = sum(3, 4)
print(result) # 输出:7
5.递归函数:在一个函数的函数体内调用该函数本身的函数。
一个完整的递归操作由两部分组成 :①递归调用条件;②递归终止条件(一般用if else结构)。
def fibonacci(n):
"""计算斐波那契数列的第 n 个数,斐波那契数列:f(n)=f(n-1)+f(n-2) """
if n < 2:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
# 调用递归函数
result = fibonacci(6)
print(result) # 输出:8
6.常用的内置函数
①数据类型转换类
函数名称 | 描述说明 |
bool(obj) | 获取指定对象obj的布尔值 |
str(obj) | 将指定对象obj转成字符串类型 |
int(x) | 将x转成int类型 |
float(x) | 将x转成float类型 |
list(sequence) | 将序列转成列表类型 |
tuple(sequence) | 将序列转成元组类型 |
set(sequence) | 将序列转成集合类型 |
②数学类
函数名称 | 描述说明 |
abs(x) | 获取x的绝对值 |
divmod(x,y) | 获取x与y的商和余数 |
max(sequence) | 获取sequence的最大值 |
min(sequence) | 获取sequence的最小值 |
sum(iter) | 对可迭代对象进行求和运算 |
pow(x,y) | 获取x的y次幂 |
round(x,d) | 对x进行保留d位小数,结果四舍五入 |
③迭代器操作类
函数名称 | 描述说明 |
sorted(iter) | 对可迭代对象进行排序 |
reversed(sequence) | 反转序列生成新的迭代器对象 |
zip(iter1,iter2) | 将iter1与iter2打包成元组并返回一个可迭代的zip对象 |
enumerate(iter) | 根据iter对象创建一个enumerate对象 |
all(iter) | 判断可迭代对象iter中所有元素的布尔值是否都为True |
any(iter) | 判断可迭代对象iter中所有元素的布尔值是否都为False |
next(iter) | 获取迭代器的下一个元素 |
filter(function,iter) | 通过指定条件过滤序列并返回一个迭代器对象 |
map(function,iter) | 通过函数function对可迭代对象iter的操作返回一个迭代器对象 |
④常用,其他类
函数名称 | 描述说明 |
format(value,format_spec) | 将value以format_spec格式进行显示 |
len(s) | 获取s的长度或s元素的个数 |
id(obj) | 获取对象的内存地址 |
type(x) | 获取x的数据类型 |
eval(s) | 执s这个字符串所表示的Python代码 |
九、编程思想
玄乎,学完一圈再回来
十、Python中的类与对象
类是一种用于创建对象的蓝图或模板。它定义了对象的属性(状态)和方法(行为),并允许通过创建类的实例来使用这些属性和方法。类是一种抽象的概念,它描述了对象的共同特征和行为。可以将类看作是一种自定义数据类型,它定义了数据和操作数据的方法。确实抽象...还是用不大明白
对象是指在面向对象编程中的基本概念。对象是类的实例,它具有状态(属性或实例变量)和行为(方法或函数)。类是对象的模板或蓝图,它定义了对象的结构和行为。对象具有如下特点:①状态多样可变;②行为特定;③标识唯一性。
Python中“一切皆对象”
实例化:实例化是指创建一个类的对象。通过调用类的构造方法,可以创建一个对象,并将其分配给一个变量。对象是类的具体实例,它拥有类定义的属性和方法。
类名:类名是类的标识符,用于唯一标识一个类。通常使用驼峰命名法,将每个单词的首字母大写。
属性(属性也称为实例变量或成员变量):属性是类中的数据,用于存储对象的状态。每个对象都有自己的属性值。你可以在类中定义属性,并使用它们来描述对象的特征。属性可以是任何数据类型,例如整数、浮点数、字符串等。
方法:方法是类中的函数,用于定义对象的行为或操作。方法定义在类中,并与类的实例相关联。通过调用对象的方法,可以执行特定的操作或访问对象的属性。方法可以接受参数,并且可以返回一个值。
构造方法(也称为初始化方法):构造方法是一种特殊的方法,在创建对象时自动调用。它用于初始化对象的属性,并进行一些必要的设置。构造方法的名称是固定的,即__init__()
。在构造方法中,通常会接受参数,并将其用于设置对象的初始状态。
继承:继承是一种类与类之间的关系,它允许一个类派生出另一个类,并继承父类的属性和方法。通过继承,子类可以扩展或修改父类的功能,实现代码的重用和层次化设计。
属性访问:通过点运算符(.
)可以访问对象的属性和方法。例如,obj.attribute
可以访问对象obj
的属性,obj.method()
可以调用对象obj
的方法。
类的组成:
①类的属性:直接定义在类之中,在方法之外的变量;
②实例属性:定义在__init__方法中,使用self.修饰(如:self.name = xm)的变量;
③实例方法:定义在类之中的函数:自带参数self;
④静态方法:使用@staticmethod修饰的方法;
⑤类方法:使用装饰器@classmethod修饰的方法。
十一、类与对象的操作
一、动态绑定属性和方法
Python支持在不改变原来类的定义与方法的情况下动态绑定,此方法只对当前的对象实例作用,不影响其他对象和原来的类
①动态绑定属性:可以通过 obj.new_attribute = value 格式 或者 setattr()
函数 来绑定新属性
②动态绑定方法:可以通过 obj.new_method = newmethod(此处为已经定义好的新函数) 格式绑定新的方法
二、面向对象的特征
封装:封装是将数据和操作(方法)组合在一起形成一个单独的实体的过程。对象通过暴露有限的接口(公共方法)来与外部进行交互,隐藏内部的实现细节。这样可以保护数据的完整性,并提供更好的抽象和模块化。
继承:继承是一种机制,允许你定义一个新的类(子类),从现有的类(父类或基类)继承属性和方法。子类可以继承父类的公有成员与受保护成员,并可以在其基础上进行扩展、修改或重写。继承提供了代码重用和层次化组织的能力,使得类与类之间建立起了关系。(基本继承语法结构:class 子类名(父类名1,父类名2,...):子类设定内容......)
#继承
class Parent1:
def __init__(self, name):
self.name = name
class Parent2:
def __init__(self, age):
self.age = age
class Child(Parent1, Parent2):
def __init__(self, name, age, grade):
Parent1.__init__(self, name) # 调用 Parent1 的构造函数,传递 name
Parent2.__init__(self, age) # 调用 Parent2 的构造函数,传递 age
self.grade = grade
# 创建子类对象
child_obj = Child("Alice", 10, 5)
# 访问继承的属性
print(child_obj.name) # 输出:Alice
print(child_obj.age) # 输出:10
print(child_obj.grade) # 输出:5
#重写
class Child2(Parent1, Parent2):
def __init__(self, name, age, grade):
Parent1.__init__(self, name) # 调用 Parent1 的构造函数,传递 name
Parent2.__init__(self, age) # 调用 Parent2 的构造函数,传递 age
self.grade = grade
# 要重写直接重新写一个就行
def greet(self):
print(f"Child says hey, I am in grade {self.grade}!")
# 创建子类对象
child2_obj = Child2("Alice", 10, 5)
# 调用继承的方法(但内容其实是重写的)
child2_obj.greet() # 输出:Child says hey, I am in grade 5!
多态:多态性是指同一种操作或方法可以应用于不同类型的对象(压根不鸟对象是个啥),并产生不同的行为。多态性通过方法的重写和方法的重载来实现。方法的重载是指在同一个类中定义多个具有相同名称但参数不同的方法。(不改就是默认值,改了就是新值)
class Animal:
def make_sound(self):
pass
class Dog(Animal):
def make_sound(self):
print("Woof!")
class Cat(Animal):
def make_sound(self):
print("Meow!")
# 创建不同的对象
animal1 = Animal()
animal2 = Dog()
animal3 = Cat()
# 调用相同的方法,但产生不同的行为
animal1.make_sound() # 不输出任何内容
animal2.make_sound() # 输出:Woof!
animal3.make_sound() # 输出:Meow!
三、权限控制
通过对属性或者方法的格式的修改来实现权限表示与控制
单下划线开头(protected):表示受保护的成员,被视为仅供内部使用,允许类本身和子类进行访问(实际上可以被外部代码访问)
双下划线(private):表示私有的成员,这一类成员只允许定义了该属性或方法的类本身进行访问。即这一类成员其实是为了类里面的其他方法服务的(类似于JS中在函数内创建一个局部变量,仅仅在该函数内有用,当然,他有办法被调用,但是会破坏代码的封装性,不建议)
首尾双下划线:一般表示特殊方法
四、object类
所有的类的父类或者间接父类与所有类的基类。它是所有内置类和用户自定义类的默认超类。(即类的“默认值”)
object
类定义了一些基本的方法和特殊方法,这些方法可以在所有对象上调用。一些常见的内置方法包括 __init__()
、__str__()
、__repr__()
、__eq__()
、__hash__()
等。(所以实际上我们是在继承此父类的方法来编写的,这里的__init__其实也就是个方法而已)
由于所有类都直接或间接地继承自 object
类,因此它提供了一些通用的功能和行为,例如对象的创建和销毁、对象的字符串表示形式、对象的比较等。
五、特殊方法
以现阶段的知识,我们可以将数据(如字符,数字)看为一个被定义过的类的实例化对象,因此他们所属的类其实都包含有方法,这种内置的方法常被称为特殊方法
如我们对两个数字使用 + 运算符,其实就是调用了数字这个对象所属的类里面的__add__()方法。
特殊方法的调用通常是由 Python 解释器自动处理的,根据对象的类型和上下文来决定调用哪个特殊方法。这使得我们可以使用自定义类对象与 Python 内置功能无缝地交互,使其行为类似于内置类型的对象。总结来说,特殊方法是在类定义中使用特定命名的方法,用于定义自定义类与 Python 内置功能的交互方式。通过实现这些方法,我们可以定制类的行为,使其具有特定的语义和行为特征。
六、特殊属性
特殊属性通常以首尾双下划线标示,是具有特殊含义或用途的属性,在对象的命名空间中以特殊的属性名称存在。它们可用于获取对象的名称、类、属性字典等特定信息,或控制对象的行为和功能。
七、变量赋值与拷贝(copy模块)
变量赋值:形成两个变量,实际上指向同一个对象(没有在内存中开辟空间)
注意,这里指赋值时把一个对象所赋值的变量赋给另一个变量,如果通过实例化一个类创建了两个对象,并将它们赋值给两个不同的变量,且这两个对象在实例化过程中传递的参数不同,它们通常不会指向同一个对象。
浅拷贝:拷贝时对象包含的子对象内容不拷贝(不新建),因此被拷贝对象(源对象)与拷贝对象会引用同一个子对象(子对象:一个对象中包含的对象)。即源对象与拷贝对象指向的内存地址不同,但是其子对象地址相同
深拷贝:使用copy模块中的deepcopy函数,递归新建源对象中包含的子对象。源对象和拷贝对象的所有的子对象不相同。即源对象与拷贝对象的内存地址与其子对象地址都不同
十一、模块与包
一、模块的概念
Python中的一个后缀名为py的Python文件就是一个模块
它包含了一组相关的函数、变量和类定义。模块是Python代码的组织单元,它可以被其他Python程序导入和使用。可以把模块理解为一个功能的封装单元(类似网页中的JS文件),它提供了一组相关的功能和接口。而且避免了函数、类、变量名冲突的问题,使代码更为规范。
模块导入和使用:使用import语句导入,然后按正常的语法使用函数等等即可
模块命名:全小写,下划线分隔
模块名重复:优先导入自定义的模块,若导入的具有重复则后面覆盖前面(想分别使用就使用import导入后使用 模块名.函数 以避免重复)
二、包的概念
包(Package)是一种组织和管理模块的方式,它将相关的模块放置在同一个文件夹中,并使用特殊的__init__.py
文件(即文件夹下应该有一个这个文件才是一个包)来标识该文件夹为一个包。
包的导入和使用:导入整个包则使用import语句,导入包中的某个模块则使用form...import语句。在包和模块后面加一句 as 可以为包和模块起一个较为简单明了的临时名字
注意事项:要在同一项目目录下
三、主程序运行
主程序是指在一个Python项目中作为入口点执行的脚本或模块。它通常包含项目的主要逻辑和控制流程,用于调用其他模块、执行函数、处理用户输入等。
主程序优点:可组织性与可扩展性、可重用性、可测试性、可维护性、用户友好性
# main.py
import sys #一个可处理命令行参数的库
from mypackage.module1 import greet
from mypackage.module2 import MyClass
def main():
# 处理命令行参数
if len(sys.argv) > 1:
name = sys.argv[1]
else:
name = "World"
# 调用模块中的函数
greet(name)
# 实例化类并调用方法
obj = MyClass(42)
obj.display()
#主程序
if __name__ == "__main__":
main()
因为按照模块导入的规则,模块中直接写在顶层(如直接写一个运行此模块就会输出的print函数)的函数会被直接执行,因此需要主程序,这样运行此主程序时才会去执行这些代码。
四、Python中常用的内置模块
与解释器一起装入的模块,也叫系统内置模块、标准模块和标准库。这有几个常用的:
五、第三方模块
第三方模块安装:pip install 模块名称
第三方模块卸载:pip uninstall 模块名称
升级pip命令:python -m pip install --upgrade pip
常用的第三方模块:①爬虫类:requests、beautifulsoup4、scrapy、selenium、pandas、scrapy-redis、ryquery、pillow、pytesseract、proxypool、splash、scrapy-useragents、pyppeteer、furl、peewee、scrapy-rotating-proxies
②Excel处理:openpyxl、pandas、xlsxwriter
③加密内容处理:cryptography、PyCryptodome、bcrypt、passlib
④图片处理:Pillow、OpenCV、scikit-image、matplotlib、PIL
⑤数据处理:pandas、NumPy、matplotlib、seaborn、scikit-learn
⑥数据可视化:pyecharts、
⑦中文内容处理类:jieba、SnowNLP、NLTK、HanLP、THULAC
⑧Python程序与文件的处理:PyInstaller、cx_Freeze、py2exe、Py2App、PyOxidizer
总结:要啥学啥()
十二、文件与文件操作
文件是计算机系统中存储数据的基本单位。它是一种命名的、有序的数据集合,可以包含文本、图像、音频、视频等各种类型的数据。文件通过文件系统进行组织和管理。通常由文件名和扩展名组成。
Python中操作文件的基本方法:
①打开
file = open("filename.txt", "r") # 打开文件以供读取
②读取
content = file.read() # 读取整个文件内容
print(content)
③逐行读取
for line in file:
print(line)
④写入
file = open("filename.txt", "w") # 打开文件以供写入
file.write("Hello, World!") # 写入内容
file.close() # 关闭文件
⑤ OS模块操作
import os
# 检查文件是否存在
if os.path.exists("filename.txt"):
print("文件存在")
else:
print("文件不存在")
# 获取文件大小
size = os.path.getsize("filename.txt")
print("文件大小:", size, "字节")
# 删除文件
os.remove("filename.txt")
#重命名
os.rename("old_filename.txt", "new_filename.txt")
#复制
shutil.copy("source_file.txt", "destination_file.txt")
#删除
os.remove("filename.txt")
#获取绝对路径
absolute_path = os.path.abspath("filename.txt")
print("文件的绝对路径:", absolute_path)
#检查路径
path = "filename.txt"
if os.path.isfile(path):
print(path, "是一个文件")
else:
print(path, "不是一个文件")
#列出目录中的文件和子目录
directory = "path/to/directory"
contents = os.listdir(directory)
for item in contents:
print(item)
⑥文件的基本操作:打开方式:"r":只读模式(默认)。"w":写入模式。"a":追加模式。"x":独占创建模式。"b":二进制模式。"t":文本模式(默认)。"+":更新模式。
⑦with语句: with
语句是 Python 中的一种上下文管理器,它提供了一种优雅的方式来处理资源的获取和释放,确保在使用完资源后自动进行清理操作。基本语法:
with 上下文表达式 [as 文件别名]:
with open("filename.txt", "r") as file:
content = file.read()
# 对文件内容进行操作
# 文件会在代码块结束时自动关闭
十三、多维度数据与操作
①一维数据:列表与元组之类的,最常见;
②二维数据:一般由列表嵌套列表组成,如果要查找或者遍历都需要“双重操作”
matrix = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
element = matrix[1][2] # 访问第二行第三列的元素,值为 6
matrix = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
for row in matrix:
for element in row:
print(element) # 逐个打印所有元素
matrix = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
matrix[0][1] = 10 # 将第一行第二列的元素修改为 10
#CSV(逗号分隔值)是一种常见的文本文件格式,适用于存储二维数据。可以使用 Python 内置的 csv 模块#来读写 CSV 文件。
import csv
# 写入 CSV 文件
data = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
with open('data.csv', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerows(data)
# 读取 CSV 文件
with open('data.csv', 'r') as file:
reader = csv.reader(file)
data = list(reader)
#JSON(JavaScript 对象表示法)是一种常见的数据交换格式,可以用来存储二维和高维数据。可以使用 #Python 内置的 json 模块来读写 JSON 文件。
import json
# 写入 JSON 文件
data = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
with open('data.json', 'w') as file:
json.dump(data, file)
# 读取 JSON 文件
with open('data.json', 'r') as file:
loaded_data = json.load(file)
③高维数据:最常见的就是列表套字典 ,常使用json模块
插入:json模块的常用函数
④目录与文件:主要由OS模块进行操作,随计算机系统不同而有所不同,
numpy
numpy中的基本函数与使用:
NumPy是Python中用于数值计算的核心库,提供了丰富的数组操作函数。
numpy.array()
: 创建一个数组。numpy.arange()
: 创建一个等差数组。numpy.linspace()
: 创建一个等间隔数组。numpy.zeros()
: 创建一个全零数组。numpy.ones()
: 创建一个全一数组。numpy.eye()
: 创建一个单位矩阵。numpy.random.rand()
: 生成随机数组。numpy.reshape()
: 改变数组的形状。numpy.concatenate()
: 连接数组。numpy.vstack()
: 垂直堆叠数组。numpy.hstack()
: 水平堆叠数组。numpy.split()
: 分割数组。numpy.argmax()
: 返回最大值的索引。numpy.argmin()
: 返回最小值的索引。numpy.max()
: 返回最大值。numpy.min()
: 返回最小值。numpy.mean()
: 返回平均值。numpy.median()
: 返回中位数。numpy.sum()
: 返回数组元素的总和。numpy.dot()
: 计算两个数组的点积。
十四、网络协议概述
此处仅表概念:
七层网络中包含的所有协议如下:
-
物理层(Physical Layer):
- 协议:Ethernet、RS-232、RS-485、USB、HDMI、Wi-Fi等。
-
数据链路层(Data Link Layer):
- 协议:Ethernet、Wi-Fi、Bluetooth、PPP(Point-to-Point Protocol)、HDLC(High-Level Data Link Control)等。
-
网络层(Network Layer):
- 协议:IP(Internet Protocol)、ICMP(Internet Control Message Protocol)、ARP(Address Resolution Protocol)、RIP(Routing Information Protocol)、OSPF(Open Shortest Path First)等。
-
传输层(Transport Layer):
- 协议:TCP(Transmission Control Protocol)、UDP(User Datagram Protocol)、SCTP(Stream Control Transmission Protocol)等。
-
会话层(Session Layer):
- 协议:RPC(Remote Procedure Call)、NetBIOS(Network Basic Input/Output System)等。
-
表示层(Presentation Layer):
- 协议:TLS(Transport Layer Security)、ASCII(American Standard Code for Information Interchange)、JPEG(Joint Photographic Experts Group)等。
-
应用层(Application Layer):
- 协议:HTTP(Hypertext Transfer Protocol)、FTP(File Transfer Protocol)、SMTP(Simple Mail Transfer Protocol)、DNS(Domain Name System)、DHCP(Dynamic Host Configuration Protocol)、SSH(Secure Shell)等。
-
详细的建议看专门视频,此处因本人学习过相关知识,故此处暂且不表。
十五、Python中的TCP编程
一、基本的socket模块的方法:
-
bind(address)
:- 作用:将套接字绑定到指定的地址和端口。
- 用法:
socket.bind(address)
,其中address
是一个包含IP地址和端口号的元组。
-
listen(backlog)
:- 作用:开始监听连接请求,使套接字进入监听状态。
- 用法:
socket.listen(backlog)
,其中backlog
指定等待连接队列的最大长度。
-
accept()
:- 作用:接受客户端的连接请求,返回一个新的套接字对象和客户端地址。
- 用法:
socket.accept()
,返回值是一个包含新套接字和客户端地址的元组。
-
connect(address)
:- 作用:与服务器建立连接。
- 用法:
socket.connect(address)
,其中address
是服务器的地址和端口号。
-
recv(bufsize)
:- 作用:接收并返回从连接的另一端接收的数据。
- 用法:
socket.recv(bufsize)
,其中bufsize
指定要接收的最大字节数。
-
send(bytes)
:- 作用:发送数据到连接的另一端。
- 用法:
socket.send(bytes)
,其中bytes
是要发送的字节流。
-
sendall(bytes)
:- 作用:完整地发送所有数据到连接的另一端,直到发送完所有字节。
- 用法:
socket.sendall(bytes)
,其中bytes
是要发送的字节流。
-
recvfrom(bufsize)
:- 作用:接收并返回从连接的另一端接收的数据,同时返回数据的来源地址。
- 用法:
socket.recvfrom(bufsize)
,其中bufsize
指定要接收的最大字节数。
-
sendto(bytes, address)
:- 作用:将数据发送到指定的地址和端口。
- 用法:
socket.sendto(bytes, address)
,其中bytes
是要发送的字节流,address
是目标地址和端口号的元组。
-
close()
:- 作用:关闭套接字连接。
- 用法:
socket.close()
。
二、
流程外的知识:
一、装饰器
装饰器是一种特殊的语法构造,用于修改或扩展函数的行为。装饰器本质上是一个函数,它接受一个函数作为输入,并返回一个新的函数作为输出。这个新的函数通常包装或装饰了原始函数,以便在执行原始函数之前或之后执行一些额外的代码。饰器提供了一种优雅而简洁的方式来修改函数的功能,而无需修改原始函数的定义。它们可以用于实现日志记录、性能分析、输入验证、缓存等功能,以及其他许多横切关注点。
语法:使用@符号,紧跟着装饰器函数的名称。当定义一个函数时,在函数的上方使用装饰器语法,可以将该函数传递给装饰器进行处理。
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
execution_time = end_time - start_time
print(f"函数 {func.__name__} 的执行时间为: {execution_time} 秒")
return result
return wrapper
@timing_decorator
def my_function():
# 假装这里有一些复杂的操作
time.sleep(2)
my_function()
二、魔术方法(双下方法)
其命名形式为 __方法名__
,这些方法在类中具有特殊的用途和行为。这些特殊方法通常被称为魔术方法或双下方法
以下是一些常见的特殊方法:
__str__(self)
: 当使用str(obj)
函数或print(obj)
语句时调用,返回对象的字符串表示。__repr__(self)
: 当使用repr(obj)
函数调用时调用,返回对象的“官方”字符串表示,通常是可以用来重建对象的表达式。__len__(self)
: 当使用len(obj)
函数调用时调用,返回对象的长度。__getitem__(self, key)
: 当通过索引访问对象时调用,例如obj[key]
。__setitem__(self, key, value)
: 当通过索引设置对象的值时调用,例如obj[key] = value
。__delitem__(self, key)
: 当通过索引删除对象的值时调用,例如del obj[key]
。__iter__(self)
: 当对象需要进行迭代时调用,返回一个迭代器对象。__next__(self)
: 当迭代器对象需要获取下一个值时调用,返回序列中的下一个值。__enter__(self)
和__exit__(self, exc_type, exc_val, exc_tb)
: 用于实现上下文管理器,定义了进入和退出上下文时的行为。
三、迭代器
迭代器是一个用于遍历可迭代对象的对象。他通过实现特定的方法来提供逐个访问元素的功能,而不需要事先将所有元素存储在内存中。
迭代器的两个基本方法:①__iter__方法:返回迭代器对象自身。它允许迭代器在进行迭代时被多次使用。②__next__()方法:返回迭代器中的下一个元素。如果没有更多的元素可供迭代,它会引发 StopIteration
异常。
迭代器的工作方式是,当你对可迭代对象(如列表、字符串或自定义类)调用 iter()
函数时,它将返回一个迭代器对象。然后,你可以使用 next()
函数来逐个获取迭代器中的元素,直到达到迭代结束的条件为止。
#由于知识所限,以下为gpt提供的一个迭代器使用案例
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.data):
raise StopIteration
value = self.data[self.index]
self.index += 1
return value
my_list = [1, 2, 3, 4, 5]
my_iterator = iter(my_list)
print(next(my_iterator)) # 输出: 1
print(next(my_iterator)) # 输出: 2
print(next(my_iterator)) # 输出: 3
三、私有方法的修饰调用
虽然私有属性和方法不能直接访问,但它们并不是完全无法访问的。Python使用了一种名称修饰(name mangling)的机制,在名称前面添加了一个下划线和类名来改变其实际名称。这样,我们仍然可以通过 _类名__私有属性
或 _类名__私有方法
的方式访问或调用私有成员:
class MyClass:
def __init__(self):
self.__private_attribute = 42
def __private_method(self):
print("This is a private method.")
def public_method(self):
print("This is a public method.")
self.__private_method()
obj = MyClass()
print(obj.__private_attribute) # 无法直接访问,会引发 AttributeError
obj.__private_method() # 无法直接调用,会引发 AttributeError
obj.public_method() # 可以调用,通过公共方法间接调用私有方法
print(obj._MyClass__private_attribute) # 可以通过名称修饰访问私有属性
obj._MyClass__private_method() # 可以通过名称修饰调用私有方法
套接字
套接字(Socket)是在网络编程中使用的一种抽象概念,它提供了一种通信机制,使不同计算机之间能够通过网络进行数据交换。
套接字可以看作是网络通信的一种端点,类似于电话中的插座。它允许应用程序通过网络发送和接收数据。套接字提供了一组方法和属性,用于创建、绑定、监听和连接网络连接,以及发送和接收数据。