# python学习

# 安装python解释器

  1. 跳转到官网 python,点击跳转到官网 (opens new window)
  2. 下载(我现在直接选了最新的版本)
    1. 如图:image
  3. 下载好后,点击运行,出现安装界面
  4. Add Python 3.12.1 to PATH 打上钩,点击Install Now 开始安装
  5. 安装成功
    1. 如图: image
  6. 运行Python,如图,进入Python交互环境中
    1. 如图:image
  7. 备注:现在默认安装,地址为:C:\Users\14183\AppData\Local\Programs\Python

# 使用vscode开发,需要怎么做

  1. 安装Python插件
    1. 如图:image
  2. 选择Python解释器
    1. 在vscode界面下,按键盘快捷键:F1(或者Ctrl+Shift+P)
    2. 在命令栏中输入Python:Select Interpreter,如下图所示:
      1. 如图:image
  3. 选择一下,前面安装的python解释器就行(忘记截图了)

# 使用虚拟环境(有助于确保项目的独立性和可移植性)

  1. 安装虚拟环境pip install virtualenv
  2. 管理虚拟环境
    1. 以下是直接使用(不好用,建议使用2"管理虚拟环境工具")
      1. 创建虚拟环境 输入命令:virtualenv 环境名 (如果有多个python版本,可以通过命令:virtualenv -p python路径 环境名,来创建虚拟环境)
      2. 进入环境下Scripts文件夹下 输入命令执行脚本:activate
      3. 接下来就可以在该虚拟环境下pip安装包或者做各种事了,比如要安装diango2.0版本就可以:pip install django==2.0
      4. 退出虚拟环境 输入命令:deactivate
    2. 管理虚拟环境工具
      1. virtualenvwrapper 安装命令:pip install virtualenvwrapper-win
      2. 创建虚拟环境
      3. mkvirtualenv 环境名 会统一在当前用户的envs文件夹下创建,并且会自动进入到该虚拟环境下。如果不想在默认地方创建(c:\user\envs)。可以新建个环境变量 WORKON_HOHE,然后设置默认路径。
      4. 进入虚拟环境 workon 环境名
      5. 退出虚拟环境 deactivate
      6. 删除虚拟环境 rmvirtualenv 环境名
      7. 列出虚拟环境 lsvirtualenv
      8. 进入到虚拟环境目录 cdvirtualenv 环境名

# python基础语法

# 字面量

  1. 字面量:被写下来的固定的值
  2. 常见字面量类型:整数、浮点数、字符串
  3. 举例:print(字面量),print(10)输出整数10。

# 注释

  1. 单行注释
    1. #
    2. 举例:# 注释内容
  2. 多行注释
    1. 一对三个双引号(内容可换行)
    2. 举例:"""本代码演示了:"""

# 变量

  1. 在程序运行时,能存储计算结果或能表示值的抽象概念。
  2. 变量名 = 变量值

# 数据类型

type(变量) 可以输出类型
print(type("123")) 输出结果:<class 'str'>
print(type(12.2345566)) 输出结果: <class 'float'>

# 数据类型转换

  1. int(x) 将x转换为一个整数
  2. float(x) 将x转换为一个浮点数
  3. str(x) 将x转换为字符串

# 标识符

# 标识符规则

标识符命名,只允许出现

  1. 内容限定
    1. 英文
    2. 中文
    3. 数字
    4. 下划线
    5. 注意:数字不可以开头
    6. 注意:不推荐使用中文
  2. 大小写敏感
  3. 不可使用关键字

# 标识符规范

不同标识符(变量名、类名、方法名)有不同的规范; 变量:明了、简洁、小写

# 运算符

  1. 算数运算符
    1. / 除
    2. // 取整除 9//2等于4
    3. % 取余 9%2等于1
    4. ** 指数 2**2 2的2次方等于4
  2. 赋值运算符
    1. 标准赋值
      1. = 赋值
    2. 复合赋值运算符
      1. += a+=c a=a+c
      2. -=
      3. *=
      4. /=
      5. //=
      6. %=
      7. **=

# 字符串扩展

  1. 字符串的三种定义方式

    1. 单引号
    2. 双引号
    3. 三引号(可以换行) (给变量赋值,就变成字符串,否则就是多行注释)
    4. 备注:\ 转义字符
  2. 字符串拼接

      • 拼接
  3. 字符串格式化(占位拼接)

    1. %s %d %f
      1. % 表示占位
      2. s 表示将字符串放入占位的地方f
      3. d 表示将整数放入占位的地方
      4. f 表示将浮点数放入占位的地方
    2. 举例:name = "张三" age = 18
      msg1 = "介绍:%s" %name  
      msg2 = "介绍:%s今年%d岁了" %(name, age)
      
      1
      2
  4. 字符串格式化(数字精度控制)

    1. m.n 控制数据的宽度和精度
    2. 举例
      %5d:表示整数的宽度控制在5位,比如18结果是[空格][空格][空格]18
      %6.2d:表示宽度控制在5位,小数点精度设置为2,比如18.345结果是[空格]18.35
      %.2d:表示不限制宽度,只设置小数点精度为2,比如18.345结果是18.35
      
      1
      2
      3
  5. 表达式格式化

    1. 举例
      print("1*2等于%d"%(1*2))
      print(f"2+4等于{2+4}")
      print("字符串在python中的类型名是%s",type("字符串"))
      
      1
      2
      3

# 数据输入

  1. input()
    1. 使用input()语句可以从键盘获取输入
    2. 使用一个变量接收(存储)input语句获取的键盘输入数据即可
    3. 数据是字符串类型
  2. 举例
    print("请问,你现在几岁了?")
    age = input()
    print("好的,我知道你现在%s岁了"%age)
    
    age = input("请问,你现在几岁了?")
    print("好的,我知道你现在%s岁了"%age)
    
    1
    2
    3
    4
    5
    6

# 判断语句

# 布尔类型和比较运算符

  1. 布尔类型 bool
    1. True
    2. False
  2. 比较运算符
    1. == 判断内容是否相等
    2. != 判断内容是否不相等
    3. > >=
    4. < <=

# if语句的基本格式

# if else
age = input("你今年几岁了?")
age = int(age)
if age > 18:
    print("成年了")
else:
    print("还未成年")

# if elif else
heigt = int(input("请输入您的身高"))
vip_level = int(input("请输入您的vip等级(1-5)"))
if heigt <120:
    print("不需要门票")
elif vip_level>3:
    print("vip等级超3级,门票免费。")
else:
    print("需要付费")
print("祝您玩的愉快!")

# 嵌套
if int(input("请输入您的身高")) < 120:
   print("身高小于120")
   if int(input("请输入您的vip等级(1-5)")) > 3:
      print("vip等级大于3")
      print("门票可以免费")
   else:
      print("vip等级小于3")
      print("门票不能免费")
else:
   print("身高大于120,门票不能免费")
print("祝您玩的愉快!")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 循环语句

# while

举例:

i = 0
while i < 10:
    print("循环打印%d" % i)
    i += 1


# while循环的嵌套
i = 1
while i <= 9:
   j = 1
   while j <= i:
      print(f"{j} * {i} = {i*j}\t", end="")
      j += 1
   print()
   i += 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# for

  1. 基础语法
# 例子1
# for循环
name = "assss aftd dga ssddaer"
count = 0
for x in name:
    if x == "a":
        count += 1
print(f"a有{count}个")

# 例子2
for x in range(1, 10, 3):
    print(x)
# 输出的结果是:1,4,7
1
2
3
4
5
6
7
8
9
10
11
12
13
  1. range语句
    1. 语法1 range(num)
    range(num)获取一个从0开始,到num结束的数字序列(不含num本身)
    range(5) 取得的结果是:0,1,2,3,4
    
    for x in range(5):
       print(x)
    
    1
    2
    3
    4
    5
    1. 语法2 range(num1,num2)
    range(num1,num2) 获取一个从num1开始,到num2结束的数字序列(不含num2本身)
    step 默认是1
    range(2,6) 取得的结果是:2,3,4,5
    
    1
    2
    3
    1. 语法3 range(num1,num2,step)
    range(num1,num2,step) 获取一个从num1开始,到num2结束的数字序列(不含num2本身)数字之间的步长已step为准
    range(2,6,2) 取得的结果是:2 4
    
    1
    2

# 循环中断:break和continue

# 函数

# 例子
def add(num_1, num_2, num_3):
    result = num_1 + num_2 + num_3
    return result

res = add(2, 3, 5)
print(f"结果是{res}")
1
2
3
4
5
6
7

# 函数的定义

  1. 先定义函数;后调用函数;
  2. 参数不需要,可以省略;返回值不需要,可以省略。
def 函数名(参数,参数,参数):
   函数体
   return 返回值

变量 = 函数(参数,参数,参数)
1
2
3
4
5

# 函数的参数

  1. 参数不需要,可以省略
  2. 参数也可以多个

# 函数的返回值

  1. None 字面量
    1. 如果函数没有使用return语句返回数据,其实也是有返回值的,是None
    2. 特殊字面量None:类型是<class 'NoneType'>
    3. 表示空的 没实际意义
    4. if 判断中 None表示False
  2. 函数中没有返回值,可以return None

# 函数说明文档

  1. 多行注释,写在函数体之前
  2. 鼠标悬停在调用的函数上,会弹出函数的说明文档
def add(a, b, c):
    """
    add函数可以接受三个参数,进行三个数的相加
    :param a: 形参a表示相加的其中一个数字
    :param b: 形参b表示相加的其中一个数字
    :param c: 形参c表示相加的其中一个数字
    :return: 返回的是三个数字相加的结果
    """
    result = a + b + c
    return result


res = add(2, 3, 5)
print(f"结果是{res}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 函数的嵌套调用

一个函数里面又调用了另外一个函数

def fun_a():
    print("aaaa")


def fun_b():
    print("bbbb")
    fun_a()
    print("cccc")


fun_b()

# 输出结果 bbbb aaaa cccc
1
2
3
4
5
6
7
8
9
10
11
12
13

# 变量的作用域

  1. global
# 全局变量
num = 100


def fun():
    # 局部变量
    num = 200
    print(f"输出值1为:{num}")

fun()
print(f"输出值2为:{num}")


# 此时输出的结果是: 输出值1为:200 输出值2为:100


# 函数内可以改变全部变量
# 全局变量
num = 100


def fun():
    # 设置内部定义的变量为全局变量
    # 这里的num和外面的全局变量num是同一个变量 
    global num
    num = 200
    print(f"输出值1为:{num}")


fun()
print(f"输出值2为:{num}")

# 此时输出的结果是: 输出值1为:200 输出值2为:200
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 数据容器

  1. 定义:一种可以存储多个元素的python数据类型
  2. 有哪些数据容器
    1. list(列表)
    2. tuple(元组)
    3. str(字符串)
    4. set(集合)
    5. dict(字典)

# list(列表)

  1. 定义:
    1. 变量名称=[元素1,元素2,元素3]
    2. 可以嵌套: 变量名称=[元素1,元素2,元素3,[元素4,元素5]]
    3. 定义空列表
      1. 变量名称 = []
      2. 变量名称 = list()
  2. 如下特点
    1. 可以容纳多个元素: 2**63 -1
    2. 可以容纳不同类型的元素
    3. 数据是有序存储的(有下标序号)
    4. 允许重复数据存在
    5. 可以修改(增加或删除元素)
  3. 列表的下标索引
    my_list = ["name", "age", [3, 5], 9]
    print(f"list[0]的结果是{my_list[0]}")
    print(f"list[2]的第一个的结果是{my_list[2][0]}")
    # 输出的结果是:
    # list[0]的结果是name
    # list[2]的第一个的结果是3
    
    1
    2
    3
    4
    5
    6
  4. 列表的常用操作
    1. 列表的查询方法
      1. 功能:查找指定的元素在列表的下标,如果找不到,报错ValueError
      2. 语法:列表.index(元素)
      3. index就是列表对象(变量)内置的方法(函数)
    2. 使用下标索引获取值
      my_list = ["a", "b", "c"]
      index_b = my_list.index("b")
      print(f"列表中的下标索引值是{index_b}")
      
      index_d = my_list.index("d")
      print(f"列表中的下标索引值是{index_d}")
      # 结果:ValueError: 'd' is not in list
      
      1
      2
      3
      4
      5
      6
      7
    3. 插入元素
      1. 插入元素:列表.insert(下标,元素):在指定的下标位置,插入指定的元素
      my_list = [1, 2, 3]
      my_list.insert(1, "testInsert")
      print(f"输出的结果是{my_list}")
      # 输出的结果是[1, 'testInsert', 2, 3]
      
      1
      2
      3
      4
      1. 追加元素(单个):列表.append(元素):将指定元素,追加到列表的尾部
      my_list = [1, 2, 3]
      my_list.append(4)
      print(f"输出的结果是:{my_list}")
      # 输出的结果是:[1, 2, 3, 4]
      
      1
      2
      3
      4
      1. 追加元素(一批):列表.extend(其他数据容器):将其他数据容器的内容取出,依次追加到列表的尾部
      my_list = [1, 2, 3]
      my_list.extend([4, 5, 6])
      print(f"输出的结果是:{my_list}")
      # 输出的结果是:[1, 2, 3, 4, 5, 6]
      
      1
      2
      3
      4
    4. 删除元素
      1. 语法1:del列表[下标]
      my_list = [1, 2, 3, 4, 5, 6]
      del my_list[1]
      print(f"返回的结果{my_list}")
      # 返回的结果[1, 3, 4, 5, 6]
      
      1
      2
      3
      4
      1. 语法2:列表.pop(下标)
      my_list = [1, 2, 3, 4, 5, 6]
      element = my_list.pop(2)
      print(f"输出的结果{my_list}{element}")
      # 输出的结果[1, 2, 4, 5, 6]3
      
      1
      2
      3
      4
      1. 语法3:列表.remove(元素):删除某元素在列表中的第一个匹配项
      my_list = [1, 2, 3, 2, 5, 6]
      my_list.remove(2)
      print(f"输出的结果是{my_list}")
      # 输出的结果是[1, 3, 2, 5, 6]
      
      1
      2
      3
      4
    5. 清空列表
      1. 列表.clear()
      my_list = [1, 2, 3]
      print(f"清空前的list{my_list}")
      my_list.clear()
      print(f"清空后的list{my_list}")
      # 结果是
      # 清空前的list[1, 2, 3]
      # 清空后的list[]
      
      1
      2
      3
      4
      5
      6
      7
    6. 统计元素个数
      1. 列表.count(元素):统计"某元素"在列表内的数量
      myList = [1, 2, 21, 4, 1]
      count = myList.count(1)
      print(f"统计1在当前列表中的数量为{count}")
      # 输出的结果:统计1在当前列表中的数量为2
      
      1
      2
      3
      4
      1. len(列表):统计列表内,有多少元素
      myList = [1, 2, "4", 8, 3]
      print(f"列表中有{len(myList)}个元素")
      
      1
      2
  5. 列表的遍历
    1. while
    2. for in

# tuple(元组)

  1. 定义:使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型
    1. (元素1,元素2,元素3)
    2. (元素,) -- 元组只有一个数据,这个数据后面要添加逗号
    3. 定义空元组
      1. 变量名称 = ()
      2. 变量名称 - tuple()
  2. 特点
    1. 元组同列表一样,但一旦定义完成,就不可修改.
  3. 常见操作
    1. index() 查找某个数据
    2. count() 统计某个数据在当前元组出现的次数
    3. len(元组) 统计元组内元素个数
  4. 举例
    1. 元组不能修改,但是元组里面的列表可以被修改
    t = (1, 2, 5, [4, 5, 6])
    t[3][0] = 2
    print(f"修改后的内容{t}")
    # 结果 修改后的内容(1, 2, 5, [2, 5, 6])
    
    1
    2
    3
    4

# str(字符串)

  1. 是无法修改的数据容器
  2. 常见操作
    1. 下标索引取值 name[0] name[1]
    2. index方法
      1. 举例
        my_str = "aaa bbb ccc"
        print(my_str.index("bbb"))
        # 4
        
        1
        2
        3
    3. replace方法
      1. 字符串.replace(字符串1,字符串2)
      2. 将字符串内的全部:字符串1,替换为字符串2
      3. 注意不是修改字符串本身,而是得到一个新字符串
      4. 举例:
        my_str = "abckcdabedahsdiapo"
        myStr = my_str.replace("ab", "k")
        print(f"{my_str},{myStr}")
        # abckcdabedahsdiapo,kckcdkedahsdiapo
        
        1
        2
        3
        4
    4. split方法
      1. 字符串.split(分隔符字符串)
      2. 功能:按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中
      3. 注意:字符串本身不变,而得到了一个列表对象
      4. 举例:
        my_str = "aaa,bbb,ccc,ddd,"
        my_list = my_str.split(",")
        print(f"{my_str}按照,区分的结果是{my_list}")
        # aaa,bbb,ccc,ddd,按照,区分的结果是['aaa', 'bbb', 'ccc', 'ddd', '']
        
        1
        2
        3
        4
    5. strip方法
      1. 去前后空格
      2. 去前后指定字符串
      3. 举例:
        # 去前后空格
        my_str = " ceshi ceshi test "
        myStr = my_str.strip()
        print(f"改前内容是:{my_str};改后内容是:{myStr};")
        # 改前内容是: ceshi ceshi test ;改后内容是:ceshi ceshi test;
        
        # 去前后指定字符串
        my_str = "ceshi ceshi tesct"
        myStr = my_str.strip('ct')
        print(f"改前内容是:{my_str};改后内容是:{myStr};")
        # 改前内容是:ceshi ceshi test;改后内容是:eshi ceshi tes;
        # c 和 t 都会移除,按照单个字符.
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12

# 数据容器(序列)的切片

  1. 序列是指:内容连续,有序,可使用下标索引的一类数据容器
    1. 列表、元组、字符串,均可以视为序列.
  2. 切片:从一个序列中,取出一个子序列
  3. 语法:序列[起始下标:结束下标:步长]
    1. 从指定位置开始,一次取出元素,到指定位置结束,得到一个新序列.
    2. 起始下标可以留空:视作从头开始
    3. 结束下标可以留空:视作截取到结尾
    4. 步长负数表示:反向取(起始下标和结束下标也要反向标记)
  4. 举例:
    my_list = [0, 1, 2, 3, 4, 5, 6, 7]
    list1 = my_list[1:3:2]
    print(f"现在的序列是{my_list},截取的序列结果是{list1}")
    # 现在的序列是[0, 1, 2, 3, 4, 5, 6, 7],截取的序列结果是[1]
    
    my_str ="0123456789"
    str1 = my_str[::-1]
    print(f"切片的结果是{str1}")
    # 切片的结果是9876543210
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

# set(集合)

  1. 集合的定义格式
    1. 变量名称 = {元素,元素,……,元素}
    2. 定义空集合: 变量名称 = set()
  2. 集合的特点
    1. 无序-所以不支持下标索引访问
    2. 元素不能重复
    3. 允许修改
  3. 集合的常见操作
    1. 添加新元素:集合.add("元素")
    2. 移除元素:集合.remove("元素")
    3. 随机取出元素:集合.pop()
    4. 清空集合:集合.clear()
    5. 取2个集合的差集:得到新集合,集合1和集合2不变
      1. 新集合=集合1.difference(集合2) 表示 集合1有而集合2没有的
    6. 消除2个集合的差集:集合1被修改,集合2不变
      1. 集合1.difference_update(集合2) 表示 在集合1内删除和集合2相同的元素
    7. 两个集合合并:集合3 = 集合1.union(集合2) 得到新的集合,集合1和集合2不变
    8. 统计元素的个数 len() 个数 = len(集合)
    9. 遍历元素,不能用while遍历,可以使用for循环遍历
  4. 举例:
    myset = {"1","2","1","3","2"}
    print(f"{myset}")
    # 输出的结果:{'1', '3', '2'}
    
    # 集合添加元素
    my_set = {"A", "C", "B", "D"}
    my_set.add("F")
    my_set.add("A")
    print(f"输出的结果是:{my_set}")
    # 输出的结果是:{'A', 'B', 'F', 'D', 'C'}
    
    # 集合移除元素
    my_set = {"A", "C", "B", "D"}
    my_set.remove("C")
    print(f"输出的结果是:{my_set}")
    # 输出的结果是:{'B', 'A', 'D'}
    
    # 集合随机取出元素
    my_set = {"A", "C", "B", "D"}
    elememt = my_set.pop()
    print(f"集合:{my_set},元素:{elememt}")
    # 集合:{'C', 'A', 'D'},元素B
    
    # 集合清空
    my_set = {"A", "B"}
    my_set.clear()
    print(f"输出的结果是{my_set}")
    # 输出的结果是set()
    
    # 取2个集合的差集
    myset1 = {"A","B","C"}
    myset2 = {"B","C","D"}
    # 表示:集合1有而集合2没有
    myset = myset1.difference(myset2)
    print(f"结果是{myset}")
    # 结果是{'A'}
    
    # 取2个集合的差集
    myset1 = {"A","B","C"}
    myset2 = {"B","C","D"}
    # 表示:集合1内,删除和集合2相同的元素;
    myset1.difference_update(myset2)
    print(f"myset1:结果是{myset1},myset2:结果是{myset2}")
    # 集合1被修改,集合2不变
    # myset1:结果是{'A'},myset2:结果是{'C', 'B', 'D'}
    
    # 两个集合合并
    myset1 = {"A", "B", "C"}
    myset2 = {"C", "D", "F"}
    myset3 = myset1.union(myset2)
    print(f"输出的结果是{myset3}")
    # 输出的结果是{'C', 'B', 'D', 'A', 'F'}
    
    # for循环遍历元素
    myset1 = {"A", "B", "C"}
    for e in myset1:
        print(f"遍历的元素为:{e}")
    # 结果是:
    # 遍历的元素为:A
    # 遍历的元素为:C
    # 遍历的元素为:B
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61

# dict(字典 映射)

  1. 定义:
    1. 使用{},不过存储的元素是一个个的:键值对
    2. key不重复
    3. my_dict = {key: value, key: value, ......, key: value}
  2. 定义空字典
    1. my_dict = {}
    2. my_dict = dict()
  3. 基础操作:
    my_dict1 = {"张三": 100, "李四": 92, "王五": 53}
    print(f"输出的内容是{my_dict1}")
    # 输出的内容是{'张三': 100, '李四': 92, '王五': 53}
    
    mydict_zs = my_dict1["张三"]
    print(f"输出的结果是{mydict_zs}")
    # 输出的结果是100
    
    # key value 可以是任意数据类型 (key不可为字典)
    stu_score_dict = {
        "张三": {"语文": 100, "数学": 99, "英语": 88},
        "李四": {"语文": 90, "数学": 97, "英语": 58},
    }
    print(f"学生的成绩是{stu_score_dict['张三']['语文']}")
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
  4. 常见操作
    1. 新增元素 字典[key]=value
    2. 更新元素 字典[key]=value
    3. 删除元素 字典.pop(key)
    4. 清空元素 字典.clear()
    5. 获取全部的key 字典.keys()
    6. 遍历字典 (有两种方式,看举例)
    7. 统计字典内的元素数量 len(字典)
    my_dict = {"张三": 100, "李四": 89}
    # 更新元素
    my_dict["张三"] = 99
    print(f"更新张三,结果是{my_dict}")
    # 更新张三,结果是{'张三': 99, '李四': 89}
    
    
    my_dict = {"张三": 100, "李四": 89}
    # 新增元素
    my_dict["王五"] = 87
    print(f"添加王五,结果是{my_dict}")
    # 添加王五,结果是{'张三': 99, '李四': 89, '王五': 87}
    
    my_dict = {"张三": 100, "李四": 89}
    # 删除元素
    my_dict.pop("张三")
    print(f"删除张三后的结果是{my_dict}")
    #删除张三后的结果是{'李四': 89}
    
    # 遍历字典-方式1
    my_dict = {"张三": "112", "张一": 100, "李四": 89, "王五": "234"}
    my_keys = my_dict.keys()
    print(f"keys的结果是{my_keys}")
    for element in my_keys:
        print(f"字典的key是:{element}")
        print(f"字典的value是:{my_dict[element]}")
    
    # keys的结果是dict_keys(['张三', '张一', '李四', '王五'])
    # 字典的key是:张三
    # 字典的value是:112
    # 字典的key是:张一
    # 字典的value是:100
    # 字典的key是:李四
    # 字典的value是:89
    # 字典的key是:王五
    # 字典的value是:234
    
    # 遍历字典-方式2
    my_dict = {"张三": "112", "张一": 100, "李四": 89, "王五": "234"}
    for key in my_dict:
     print(f"获取的key: {key}")
     print(f"获取的value: {my_dict[key]}")
    
    # 获取的key: 张三
    # 获取的value: 112
    # 获取的key: 张一
    # 获取的value: 100
    # 获取的key: 李四
    # 获取的value: 89
    # 获取的key: 王五
    # 获取的value: 234
    
    
    my_dict = {"张三": "112", "张一": 100, "李四": 89, "王五": "234"}
    my_dict_num =len(my_dict)
    print(f"统计字典的元素数量{my_dict_num}")
    # 统计字典的元素数量4
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57

# 数据容器的通用操作

  1. len(容器)
  2. max(容器)
  3. min(容器)
  4. 类型转换
    1. list(容器) 将容器转换为列表
    2. str(容器) 将容器转换为字符串
    3. tuple(容器) 将容器转换为元组
    4. set(容器) 将容器转换为集合
  5. 通用排序功能
    1. sorted(容器,reverse=true),将给定容器进行排序
    my_list = [1, 3, 2, 5, 4]
    print(f"排序{sorted(my_list)},{sorted(my_list,reverse=True)}")
    # 结果是 排序[1, 2, 3, 4, 5],[5, 4, 3, 2, 1]
    
    1
    2
    3

# 函数的进阶

# 函数多返回值

按照返回值的顺序,写对应顺序的多个变量接收 变量之间用逗号隔开 支持不同类型的数据return

def num_return():
    return 1, 2

x, y = num_return()
print(f"返回的数据是:{x}{y}")
# 返回的数据是:12
1
2
3
4
5
6

# 函数多种传参方式

参数使用方式:

  1. 位置参数
  2. 关键字参数
    1. 函数调用时通过"键=值"形式传递参数(清除了参数的顺序需求)
    2. 位置参数可以和关键字参数混用,位置参数必须在前,且匹配参数顺序
  3. 不定长参数
    1. 不定长参数也叫可变参数,用于不确定调用的时候会传递多少个参数(不传参也可以)的场景
    2. 不定长参数的类型:
      1. 位置不定长 *号
      2. 关键字不定长 **号
  4. 缺省参数(默认值)
    1. 缺省参数也叫默认参数,为参数提供默认值,调用函数时可不传该默认参数值,注意是由位置参数必须出现在默认参数前
  5. 举例:
# 参数使用方式
# 位置参数
def canshu_wz(num1, num2, num3):
    num = num1 + num2 + num3
    return num


a = canshu_wz(1, 2, 3)
print(f"结果是{a}")
# 结果是6


# 关键字参数
def user_info(name, age, gender):
    print(f"您的名字时:{name},年龄是{age},性别是{gender}")


# 参数的顺序没有关系
user_info(name="测试人员", gender="男", age=20)
# 您的名字时:测试人员,年龄是20,性别是男
user_info(gender="男", name="测试人员", age=20)
# 您的名字时:测试人员,年龄是20,性别是男
user_info("项目经理", gender="男", age=20)
# 您的名字时:项目经理,年龄是20,性别是男


# 缺省参数
def userinfo(name, age, gender="女"):
    print(f"您的名字时:{name},年龄是{age},性别是{gender}")


userinfo(age=18, name="aaa")
# 您的名字时:aaa,年龄是18,性别是女
userinfo(gender="男", age=18, name="aaa")
# 您的名字时:aaa,年龄是18,性别是男
userinfo("bbb", 20, "男")
# 您的名字时:bbb,年龄是20,性别是男


# 不定长参数
# 位置不定长 *号
def userinfo1(*args):
    print(f"args参数的类型是:{type(args)},内容是{args}")


userinfo1("TOM")
userinfo1("TOM", 20, True)
# 输出的结果是:
# args参数的类型是:<class 'tuple'>,内容是('TOM',)
# args参数的类型是:<class 'tuple'>,内容是('TOM', 20, True)


# 关键字不定长 **号
def userinfo2(**kwargs):
    print(f"kwargs参数的类型是:{type(kwargs)},内容是{kwargs}")


userinfo2(name="TOM", age=20, bool=True)
# kwargs参数的类型是:<class 'dict'>,内容是{'name': 'TOM', 'age': 20, 'bool': True}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# 匿名函数

  1. 举例
    # 函数作为参数传递
    # 定义一个函数,接收另一个函数作为传入参数
    def test_func(compute):
        result = compute(2, 3)
        print(result)
    
    # 定义一个函数,准备作为参数传入另一个函数
    def compute(x, y):
        return x + y
    
    # 调用,并传入函数
    test_func(compute)
    # 5
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
  2. lambda匿名函数
    1. 语法:lambda 传入参数:函数体
      1. lambda 是关键字,表示定义匿名函数
      2. 传入参数表示匿名函数的形式参数
      3. 函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
    2. 举例:
    def test_func1(compute):
       result = compute(2, 3)
       print(result)
    
    test_func1(lambda x, y: x * y)
    # 6
    # 只有lambda关键字定义的函数是匿名的,无法二次使用
    
    1
    2
    3
    4
    5
    6
    7

# python 文件操作

  1. 文件的编码:比如utf-8
  2. 文件的读取
  3. 文件的写入
  4. 文件的追加
  5. 文件操作综合案例
    1. open()打开函数
      1. 可以打开一个已经存在的文件或者创建一个新文件
      2. open(name,mode,encoding)
        1. name:是要打开的目标文件名的字符串(可以包括文件所在的具体路径)
        2. mode:设置打开文件的模式(访问模式):只读:r,写入:w,追加:a
          1. 只读-r:已只读方式打开文件.文件的指针将会放在文件的开头.这是默认模式
          2. 写入-w:打开文件只用于写入.如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除;如果该文件不存在,创建新文件.
          3. 追加-a:打开一个文件用于追加.如果该文件已存在,新的内容将会被写入到已有内容之后.如果该文件不存在,创建新文件进行写入.
        3. encoding:编码格式(推荐使用UTF-8)
        4. 示例: f = open("python.txt", "r", encoding="UTF-8")
    2. read():文件的读取
      1. 文件对象.read(num)
      2. num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,表示读取文件中的所有数据
    3. readline()
      1. 读取一行
    4. readlines()
      1. 可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素
    5. close()
      1. 文件对象.close()
      2. 关闭文件对象,关闭对文件的占用.(如果不调用close,同时程序没有停止运行,那么这个文件将一直被Python程序占用)
    6. for line in 文件对象
      1. for循环文件行,一次循环得到一行数据
    7. with open() as f
      1. 通过with open 语法打开文件
      2. 举例: with open("python.txt","r") as f: f.readlines()
      3. 在 as f 冒号下的所有代码执行完成后,文件会被自动close
    8. write():文件的写入
      1. 直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区
      2. 文件不存在,会创建新的文件
      3. 当调用flush的时候,内容会真正写入文件
      4. 这样避免频繁的操作硬盘,导致效率下降
        f = open("D:/sclFiles/b/python/python_xuexi/test.txt", "w",encoding="UTF-8")
        f.write("第二次write的内容") #内容写到内存中
        # f.flush() #将内存中积攒的内容,写入到硬盘文件中
        f.close() #close方法,内置了flush的功能
      
        f = open("D:/sclFiles/b/python/python_xuexi/test.txt", "w", encoding="UTF-8")
        f.write("第二次write的内容") #内容写到内存中
        # f.flush() #将内存中积攒的内容,写入到硬盘文件中
        f.close() #close方法,内置了flush的功能
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
    9. 文件的追加
      1. 文件不存在会创建文件
      2. 文件存在会在最后,追加写入文件
      3. 举例:
      # 打开文件
      f2 = open("D:/sclFiles/b/python/python_xuexi/test.txt", "a",   encoding="UTF-8")
      # 文件写入
      f2.write("添加内容") #如果要让加入的文字另起一行,可以写成:\n添加内容
      # 内容刷新
      f2.flush()
      
      1
      2
      3
      4
      5
      6

# Python 异常、模块与包

# 了解异常

  1. 异常就是程序过程中出现了错误,就是bug

# 异常的捕获方法

  1. 捕获异常的语法格式:
  2. # 基本语法
    try:
       # 必选
       print("可能发生错误的代码")
    except [异常 as 别名]:
       # 必选
       print("如果出现异常执行的代码")
    [else:]
       # 可选,可写可不写
       print("没有异常,执行代码")
    [finally:]
       # 可选,可写可不写
       print("无论是否异常都要执行的代码")
    
    
    # 捕获指定的异常
    try:
       print(name)
    except NameError as e:
       print("出现了变量未定义的异常")
       print(e)
       # e的输出结果是:name 'name' is not defined
    
    # 捕获多个异常
    try:
        1 / 0
    except (NameError, ZeroDivisionError) as e:
        print(e)
        # division by zero
    
    # 捕获所有异常 和基础语法一样也是捕获所有异常
    try:
        print(name)
    except Exception as e:
        print(f"捕获异常,{e}")
    # 捕获异常,name 'name' is not defined
    
    # 捕获异常的 else  (可选,可写可不写)
    try:
       name = "1"
       print(name)
    except Exception as e:
       print(e)
    else:
       print("没有异常的时候处理的代码区域")
    
    
    # 捕获异常的 finally  (可选,可写可不写)
    try:
        1 / 0
    except Exception as e:
        print(e)
        print("捕获到异常了")
    else:
        print("没有异常,执行代码")
    finally:
        print("无论是否异常都要执行的代码")
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58

# 异常的传递

# 异常具有传递性
def func01():
    print("这是func01开始")
    num = 1 / 0
    print("这是func01结束")


def func02():
    print("这是func02的开始")
    func01()
    print("这是func02的结束")


def main():
    try:
        func02()
    except Exception as e:
        print(f"捕获的异常是{e}")
    else:
        print("没有异常,正常处理")
    finally:
        print("不管是否有异常都会执行的代码")


main()

# 这是func02的开始
# 这是func01开始
# 捕获的异常是division by zero
# 不管是否有异常都会执行的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# Python模块

  1. 什么是模块
    1. 模块(Module),是一个Python文件,以.py结尾。模块能定义函数、类和变量
  2. 模块的导入
    1. 一般在开头写导入
    2. 导入的语法 [from 模块名] import [模块|类|变量|函数|*] [as 别名]
    3. 常用的组合形式:
      1. import 模块名
      2. from 模块名 import 类、变量、方法等
      3. from 模块名 import *
      4. import 模块名 as 别名
      5. from 模块名 import 功能名 as 别名
    4. Python模块:模块的导入 举例:
      # 使用import导入time模块使用sleep功能(函数)
      import time
      print("你好")
      time.sleep(5) #暂停5秒 
      print("间隔5秒,打印此段文字")
      
      from time import sleep
      print("开始")
      sleep(5)
      print("间隔5秒,打印此段文字")
      
      from time import *
      print("开始")
      sleep(5)
      print("间隔5秒,打印此段文字")
      
      import time as tt
      print("开始")
      tt.sleep(5)
      print("间隔5秒,打印此段文字")
      
      from time import sleep as sl
      print("开始")
      sl(5)
      print("间隔5秒,打印此段文字")
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
    5. Python模块:自定义模块
      1. 了解如何自定义模块并使用
        1. Python中已经帮我们实现了很多的模块,不过有时候我们需要一些个性化的模块,这就可以听过自定义模块实现。
        2. 举例:
          # my_module1.py 文件
          def test(a, b):
             print(a + b)
          
          # test_my_module.py 文件
          import my_module1
          
          my_module1.test(2, 8)
          # 10
          
          1
          2
          3
          4
          5
          6
          7
          8
          9
      2. 了解 main 变量的作用 if__name__ == "main"
        1. 用于判断一个脚本是作为模块导入还是直接运行。当一个python脚本被直接运行时,python会将其模块名设置为"main",因此if__name__ == "main"表示:“如果这个脚本是直接被运行的(而不是被导入为模块),那么执行以下代码块”。
        2. 这个代码块通常用于一些测试代码或者执行一些只有在直接运行脚本时才需要执行的操作。例如,你可能会将一些打印语句放在这个代码块中,这样它们只会在直接运行脚本时才会执行,而在被导入为模块时不会执行。

# Python包

     1. 包就是一个文件夹,里面可以存放许多Python的模块,通过包,在逻辑上将一批模块归为一类,方便使用。
     2.  包里有__init__.py 文件,可以是空的,但是要有这个文件才是包
     3. 自定义包
        1. 一下是两种导入方式
        ![images](./images/python/bao1.png)
        ![images](./images/python/bao2.png)
     4. 安装第三方包
        1. 什么是第三方包
        2. 掌握使用pip安装第三方包
           1. `pip install 包名称`
           2. 国内会快点:`pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称`
        3. pycache软件中安装包:
           ![image](./images/python/bao3.png)

# 数据可视化-案例

# Python数据和Json数据的相互转化

"""
JSON数据和Python字典的相互转换
"""
# 导入json模块
import json

data_list = [{"name": "张三", "age": 20}, {"name": "王五", "age": 21}, {"name": "李四", "age": 22}]
print(f"转换前数据类型{type(data_list)}")
# 将Python的列表数据转换为json格式
# ensure_ascii=False 可以将文字显示出来
json_str1 = json.dumps(data_list, ensure_ascii=False)
print(f"转换后数据类型{type(json_str1)}{json_str1}")

# 将Python的字典数据转换为json格式
data_dict = {"name": "张三", "age": 20}
print(f"转换前数据类型{type(data_dict)}")
json_str2 = json.dumps(data_dict, ensure_ascii=False)
print(f"转换后数据类型{type(json_str2)}{json_str2}")

# 将json格式的数据转换为Python数据
data_json = '{"name": "张三", "age": 20}'
print(f"转换前数据类型{type(data_json)}")
dict_1 = json.loads(data_json)
print(f"转换后数据类型{type(dict_1)}{dict_1}")

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# pyecharts模块

# 参考网址

pyecharts网址 (opens new window)

pyecharts画廊网址 (opens new window)

# 安装

cmd 中 pip install pyecharts

# 入门操作

# 导包
from pyecharts.charts import Line
from pyecharts.options import TitleOpts, LegendOpts, TooltipOpts, VisualMapOpts, ToolboxOpts

# 创建一个折线图对象
line = Line()

# 给折线图对象添加x轴的数据
line.add_xaxis(["张三", "李四", "王五"])

# 给折线图对象添加y轴的数据
line.add_yaxis("数学成绩", [68, 38, 98])
line.add_yaxis("语文成绩", [90, 100, 78])

# 设置全局配置项 set_global_opts
line.set_global_opts(
    # 标题
    title_opts=TitleOpts(title="成绩展示", pos_left="left", pos_top="1%"),
    # legend_opts=LegendOpts(is_show=True),
    # tooltip_opts=TooltipOpts(is_show=True),
    # visualmap_opts=VisualMapOpts(is_show=True),
    # toolbox_opts=ToolboxOpts(is_show=True)
)

# 通过render方法,将代码生成为图像
line.render()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

生成一个html文件,用浏览器打开html文件的效果如下: iamge

# 配置选项

  1. 全局配置选项
  2. 系列配置选项

# 对象 类

# 1 设计一个类(类比生活中,设计一张登记表)
class Student():
    name = None  # 记录学生姓名
    gender = None  # 记录学生性别
    nationality = None  # 记录学生国籍
    age = None  # 记录学生年龄


# 2 创建一个对象(类比生活中:打印一张登记表)
stu1 = Student()

# 3 对象属性进行赋值(类比生活中:填写表单)
stu1.name = "张三"
stu1.gender = "男"
stu1.nationality = "中国"
stu1.age = "18"


print(stu1.name)
# 张三
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 成员变量和成员方法

  1. 类中定义的属性(变量),我们称之为:成员变量
  2. 类中定义的行为(函数),我们称之为:成员方法 不仅可以定义属性,用来记录数据 也可以定义函数,用来记录行为
# 类
class Student:
    # 成员变量
    name = None
    age = None

    # 成员方法
    def say_hi(self):
        print(f"Hi,我是{self.name}")

    def say_hi2(self, msg):
        print(f"Hi,我是{self.name},{msg}")


# 创建一个对象
stu1 = Student()
stu1.name = "李四"
stu1.say_hi()
stu1.say_hi2("很高兴认识大家")

stu2 = Student()
stu2.name = "张三"
stu2.say_hi()
stu2.say_hi2("很高兴认识大家")

# Hi,我是李四
# Hi,我是李四,很高兴认识大家
# Hi,我是张三
# Hi,我是张三,很高兴认识大家
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 成员方法的定义语法

在类中定义成员方法和定义函数基本一致,但有细微区别: def 方法名(self,形参1,......,形参N): 方法体

self是必须填写的,在方法内部,想要访问类的成员变量,必须使用self

# 构造方法

  1. Python类可以使用: init()方法
  2. 可以实现:
    1. 在创建类对象(构造类)的时候,会自动执行
    2. 在创建类对象(构造类)的时候,将传入参数自动传递给__init__方法使用,借此特性可以给成员变量赋值
  3. 举例:
    class Student:
     # 可省略
     # name = None
     # gender = None
     # age = None
    
     # 构造方法
     def __init__(self, name, gender, age):
         self.name = name
         self.gender = gender
         self.age = age
    
     def say_hello(self):
         print("Hello, %s!" % self.name)
    
    
    stu1 = Student('张三', '男', 18)
    stu1.say_hello()
    print(f"他的名字是{stu1.name},性别:{stu1.gender},年龄是{stu1.   age}")
    # Hello, 张三!
    # 他的名字是张三,性别:男,年龄是18
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

# 其他内置方法(魔术方法)

前面学习的 __init__的构造方法,是Python类内置的方法之一。 这些内置的类方法,各自有各自特殊的功能,这些内置方法称之为:魔术方法

  1. init 构造方法
  2. str 字符串方法
  3. lt 小于、大于符号比较
    1. 返回值:True False
  4. le 小于等于、大于等于符号比较
  5. eq ==符号比较
class Student:
   def __init__(self, name, age):
      self.name = name
      self.age = age

   # 字符串方法
   def __str__(self):
      return f'{self.name} is {self.age} years'

   # 小于、大于符号比较 方法
   def __lt__(self, other):
      return self.age < other.age

   # 小于等于、大于等于符号比较 方法
   def __le__(self, other):
      return self.age <= other.age

   # == 符号比较 方法
   def __eq__(self, other):
      return self.age == other.age


stu1 = Student("张三", "20")
stu2 = Student("李四", "26")
print(stu1)
print(str(stu1))
# 当类对象需要被转换为字符串时,会输出如下结果(内存地址)
# <__main__.Student object at 0x0000016FE7074380>
# <__main__.Student object at 0x0000016FE7074380>
# 内存地址没有多大作用,我们可以通过__str__方法,控制类转换为字符串的行为

# 使用__str__ 字符串方法后输出的结果:
# 张三 is 20 years
# 张三 is 20 years

# 使用__lt__ 小于、大于符号比较 方法
print(stu1 < stu2)
# True
print(stu2 < stu1)
# False

# 使用小于等于、大于等于符号比较 方法
print(stu1 <= stu2)
# True

# 使用 == 符号比较 方法
print(stu1 == stu2)
# False
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

# 封装

# 私有成员

  1. 定义私有成员的方法:
    1. 私有成员变量:变量名以__开头(2个下划线)
    2. 私有成员方法:方法名以__开头(2个下划线)
  2. 特点:
    1. 私有方法无法直接被类对象使用
    2. 私有变量无法赋值,也无法获取值
  3. 类中的内部的其他成员可以使用
"""
私有成员
私有成员变量
私有成员方法
"""
class Phone:
    # 私有成员变量
    __current_voltage = 6

    def __keep_single_core(self):
        print("让CPU以单核模式运行")

    def call_by_5g(self):
        # 内部的其他成员可以使用私有变量
        if self.__current_voltage > 5:
            print("5g开启")
        else:
            # 内部的其他成员可以使用私有方法
            self.__keep_single_core()

phone = Phone()
# 私有变量无法赋值
# phone.__current_voltage = 1
# 私有变量无法获取值
# print(phone.__current_voltage)
# 私有方法无法直接被类对象使用
# phone.__keep_single_core

phone.call_by_5g()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 继承

  1. 单继承
    1. class 类名(父类名): 类内容体
  2. 多继承
    1. 即一个类可以继承多个父类,按照顺序,从左往右依次继承
    2. class 类名(父类名,父类名,父类名,……,父类N): 类内容体,如果没有内容体就直接写pass就行
    3. 父类中有重复的成员变量或成员方法,先继承的优先级高于后继承(写在最左边的内容优先级越高)
  3. 复写父类成员
    1. 子类继承父类的属性和成员方法后,如果对其“不满意”,那么可以进行复写。
  4. 子类中调用父类成员
    1. 一旦复写父类成员,那么类对象调用成员的时候,就会调用复写后的新成员。如果需要使用被复写的父类的成员,需要特殊的调用方式:
      1. 方式1
        1. 父类名.成员变量
        2. 父类名.成员方法(self)
      2. 方式2
        1. super().成员变量
        2. super().成员方法()
"""
继承
"""


class Phone:
    IMEI = None
    producer = "kl"

    def call_by_4g(self):
        print("4g通话")

"""
单继承
"""
class Phone2024(Phone):
    face_id = "123456"
    def call_by_5g(self):
        print("新功能,5g通话")
    def print_producer(self):
        print(self.producer)


phone = Phone2024()
phone.call_by_4g()
# 4g通话
phone.print_producer()
# kl




"""
多继承
"""

class NFCReader:
    nfc_type = "第五代"
    producer = "kl_nfc"

    def read_card(self):
        print("NFC读卡", self.nfc_type, self.producer)

    def write_card(self):
        print("NFC写卡", self.nfc_type, self.producer)


class RemoteControl:
    rc_type = "红外遥控"
    producer = "kl_hw"


    def control(self):
        print("红外遥控开启了")


class PhoneA:
    def call_by_4g(self):
        print("输出")


class Func(NFCReader, RemoteControl, PhoneA):
    pass


func = Func()
func.read_card()
func.control()
func.call_by_4g()
# 多个父类中有重复的成员变量,写在最左边的内容优先级越高
print(func.producer)
# kl_nfc



"""
复写
"""
class PhoneB:
    a = "1"

    def call_by_5g(self):
        print(f"5g通信{self.a}")


class PhoneC(PhoneB):
    # 复写属性
    a = "3"

    # 复写方法
    def call_by_5g(self):
        print("复写为新的内容")


phone_c = PhoneC()
phone_c.call_by_5g()
# 复写为新的内容"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

# 类型注解

# 变量的类型注解

  1. 方式1:变量:类型
  2. 方式2:注释中进行类型注释:# type:int
"""
方式1
"""

# 基础数据类型注解
var_1: int = 10
var_2: str = "itheima"
var_3: bool = True


# 类对象类型注解
class Student:
    pass


stu: Student = Student()

# 基础容器类型注解
my_list: list = [1, 2, 3]
my_tuple: tuple = (1, 2, 3)
my_dict: dict = {"itheima": 666}

# 容器类型详细注解
my_list: list[int] = [1, 2, 3]
# 元组需要将每个元素标记出来
my_tuple: tuple[int, str, bool] = (1, "itheima", True)
# 字典 需要2个类型,第一个是key第二个是value
my_dict: dict[str, int] = {"itheima": 666}

"""
方式2
"""
var_1 = random.randint(1,10)  # type:int
var_1 = json.loads({"name":"zhangsan"})  # type:json
   
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 函数的类型注解-形参

def 函数方法名(形参名:类型,形参名:类型,……): pass

def add(x:int,y:int):
    return x + y
1
2

# 函数的类型注解-返回值

def 函数方法名(形参名:类型,形参名:类型,……)->返回值类型: pass

# Union类型

变量、函数(方法)形参和返回值注解

# 变量注解
Union[类型,……,类型]

# 包导入
from typing import Union

my_list: list[Union[int, str]] = [1, 2, "itheima", "itcast"]
my_dict: dict[str, Union[int, str]] = {"name": "zhangsan", "age": 31}

# 函数形参注解
# 函数返回值注解
def func(data:Union[int,str]) ->union[int,str]:
   pass
1
2
3
4
5
6
7
8
9
10
11
12
13

# 多态

  1. 什么是多态:
    1. 多态指的是,同一个行为,使用不同的对象获取不同的状态.
  2. 什么是抽象类(接口)
    1. 包含抽象方法的类.抽象方法是指:没有具体实现的方法pass
  3. 抽象类的作用
    1. 多用于做顶层设计(设计标准),以便子类做具体实现
    2. 也是对子类的一种软性约束,要求子类必须复写(实现)父类的一些方法

"""
多态
"""


class AC:
    def cool_wind(self):
        pass

    def hot_wind(self):
        pass


class midea_AC(AC):
    def cool_wind(self):
        print("美的冷风方法")

    def hot_wind(self):
        print("美的热风方法")


class gree_AC(AC):
    def cool_wind(self):
        print("格力冷风方法")

    def hot_wind(self):
        print("格力热风方法")


def contrl_fun(ac: AC):
    ac.cool_wind()


midea = midea_AC()
gree = gree_AC()

contrl_fun(midea)
contrl_fun(gree)

# 美的冷风方法
# 格力冷风方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# python操作mysql

# 安装第三方库pymysql

pip install pymysql

简单使用:

"""
使用第三方的库pymysql
python操作mysql

1. 安装第三方包:pip install pymysql
"""

from pymysql import Connection

conn = Connection(
    host='localhost',
    port=3306,
    user='root',
    password='123456'
)
# 输出版本信息测试(没有报错就是链接成功)
print(conn.get_server_info())
# 11.3.0-MariaDB

# 关闭链接
conn.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 执行sql语句

# 执行非查询性质的sql语句

from pymysql import Connection

conn = Connection(
    host='localhost',
    port=3306,
    user='root',
    password='123456'
)

# 获取游标对象
cursor = conn.cursor()
# 选择数据库
conn.select_db('my_db')
# 使用游标对象,执行sql语句
cursor.execute("create table test_pymysql(id int , info varchar(255))")

# 关闭链接
conn.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 执行查询性质的sql语句

from pymysql import Connection

conn = Connection(
    host='localhost',
    port=3306,
    user='root',
    password='123456'
)

cursor = conn.cursor()
conn.select_db('my_db')
sql = "select * from table1"
cursor.execute(sql)
# 获取查询结果
results = cursor.fetchall()

print(results, type(results))
# ((1, '张三', 1), (2, '张三', 2), (3, '李四', 1)) <class 'tuple'>

for result in results:
    print(result)

# (1, '张三', 1)
# (2, '张三', 2)
# (3, '李四', 1)

conn.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 执行sql语句插入数据到mysql

# 执行sql语句插入数据到mysql
from pymysql import Connection

conn = Connection(
    host='localhost',
    port=3306,
    user='root',
    password='123456',
    autocommit=True  # 不想手动确认,设置自动提交
)
conn.select_db('my_db')
cursor = conn.cursor()
sql = "INSERT INTO table1 VALUES (NULL, '李五', 2), (NULL,'刘刘',1)"
cursor.execute(sql)
# 手动 通过commit确认
# conn.commit()
# 关闭链接
conn.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 案例,读取文件数据且将数据导入数据库表中

案例使用到的数据文件在./files/sql文件夹中、

# main.py 文件
"""
将文件数据导入数据库
1. 设计一个类,可以完成数据的封装
2. 设计一个抽象类,定义文件读取的相关功能,并使用子类实现具体功能
3. 读取文件,生产数据对象
4. 导入数据库
"""
from file_define import TextFileReader, JsonFileReader
from data_define import Record
from pymysql import Connection

text_file_reader = TextFileReader('D:/sclFiles/b/python/python_xuexi/py_sql/读取数据且导入数据库/2011年1月销售数据.txt')
json_file_reader = JsonFileReader(
    'D:/sclFiles/b/python/python_xuexi/py_sql/读取数据且导入数据库/2011年2月销售数据JSON.txt')

text_data: list[Record] = text_file_reader.read_data()
json_data: list[Record] = json_file_reader.read_data()

all_data: list[Record] = text_data + json_data

# 数据库内容
conn = Connection(
    host='localhost',
    port=3306,
    user='root',
    password='123456',
    autocommit=True
)

cursor = conn.cursor()
conn.select_db('my_db')

# 数据导入
for data in all_data:
    sql = f'insert into orders values("{data.date}", "{data.order_id}", "{data.money}","{data.province}")'
    cursor.execute(sql)

conn.close()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# data_define.py 文件
"""
数据定义的类
"""


class Record:
    def __init__(self, date, order_id, money, province):
        self.date = date
        self.order_id = order_id
        self.money = money
        self.province = province

    def __str__(self):
        return f"date: {self.date}, order_id: {self.order_id}, money: {self.money}, province: {self.province}"

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# file_define.py 文件
"""
和文件相关的类定义
"""
import json

from data_define import Record


# 先定义一个抽象类,用来做顶层设计,确定有哪些功能需要实现

class FileReader:

    def read_data(self) -> list[Record]:
        """ 读取文件的数据,读到的每一条数据都转换位Record对象,将它们封装到list内返回即可"""
        pass


class TextFileReader(FileReader):
    def __init__(self, path):
        self.path = path

    def read_data(self) -> list[Record]:
        f = open(self.path, 'r', encoding='utf-8')
        record_list = []
        for line in f.readlines():
            line = line.strip()
            data_line = line.split(",")
            record = Record(data_line[0], data_line[1], int(data_line[2]), data_line[3])
            record_list.append(record)

        f.close()
        return record_list


class JsonFileReader(FileReader):
    def __init__(self, path):
        self.path = path

    def read_data(self) -> list[Record]:
        f = open(self.path, 'r', encoding='utf-8')
        record_list = []
        for line in f.readlines():
            data_dict = json.loads(line)
            record = Record(data_dict['date'], data_dict['order_id'], int(data_dict['money']),
                            data_dict['province'])
            record_list.append(record)
        f.close()
        return record_list


if __name__ == '__main__':
    text_file_reader = TextFileReader(
        'D:/sclFiles/b/python/python_xuexi/py_sql/读取数据且导入数据库/2011年1月销售数据.txt')
    json_file_reader = JsonFileReader(
        'D:/sclFiles/b/python/python_xuexi/py_sql/读取数据且导入数据库/2011年2月销售数据JSON.txt')

    list1 = json_file_reader.read_data()
    list2 = text_file_reader.read_data()

    for l in list1:
        print(l)

    for l in list2:
        print(l)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65

# PySpark

# Spark是什么

Apache Spark是用于大规模数据处理的统一分析引擎。
Pyspark是spark官方开发的Python语言第三方库。

# 准备

# 安装PySpark

pip install pyspark

# 构建pyspark执行环境入库对象

pyspark的执行环境入口对象是:类SparkContext的类对象

"""
演示获取PySpark的执行环境入库对象:SparkContext
并通过SparkContext对象获取当前PySpark的版本
"""

# 导包
from pyspark import SparkConf, SparkContext
# 创建SparkConf类对象
conf = SparkConf().setMaster("local[*]").setAppName("test_spark_app")
# 基于SparkConf类对象创建SparkContext对象
sc = SparkContext(conf=conf)
# 打印PySpark的运行版本
print(sc.version)
# 停止SparkContext对象的运行(停止PySpark程序)
sc.stop()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# PySpark的编程模型

SparkContext类对象是PySpark编程中一切功能的入口 PySpark编程,主要分为三大步骤:数据输入、数据计算、数据输出

# 数据输入

数据输入完成后,都会得到一个RDD(弹性分布式数据集)类的对象

"""
演示通过PySpark代码加载数据,即数据输入
"""
from pyspark import SparkConf, SparkContext

conf = SparkConf().setMaster("local[*]").setAppName("test_spark")
sc = SparkContext(conf=conf)

# # 通过parallelize方法将Python对象加载到Spark内,成为RDD对象
# rdd1 = sc.parallelize([1, 2, 3, 4, 5])
# rdd2 = sc.parallelize((1, 2, 3, 4, 5))
# rdd3 = sc.parallelize("abcdefg")
# rdd4 = sc.parallelize({1, 2, 3, 4, 5})
# rdd5 = sc.parallelize({"key1": "value1", "key2": "value2"})
#
# # 如果要查看RDD里面有什么内容,需要用collect()方法
# print(rdd1.collect())
# print(rdd2.collect())
# print(rdd3.collect())
# print(rdd4.collect())
# print(rdd5.collect())

# 用过textFile方法,读取文件数据加载到Spark内,成为RDD对象
rdd = sc.textFile("D:/hello.txt")
print(rdd.collect())
rdd.map()
sc.stop()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 数据计算

RDD对象内置丰富的:成员方法(算子)

# map 算子
"""
演示RDD的map成员方法的使用
"""
from pyspark import SparkConf, SparkContext
import os

os.environ['PYSPARK_PYTHON'] = "C:/Users/14183/AppData/Local/Programs/Python/Python312/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")
sc = SparkContext(conf=conf)

# 准备一个RDD
rdd = sc.parallelize([1, 2, 3, 4, 5])
print(rdd.collect())


# 通过map方法将全部数据都乘以10
def func(data):
    return data * 10


# rdd2 = rdd.map(func)
rdd2 = rdd.map(lambda x: x * 10)
# 链式调用
# rdd2 = rdd.map(lambda x: x * 10).map(lambda x: x + 5)

print(rdd2.collect())
# (T) -> U
# (T) -> T


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# flatMap算子

扁平化

"""
演示RDD的flatMap成员方法的使用
"""
from pyspark import SparkConf, SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "C:/Users/14183/AppData/Local/Programs/Python/Python312/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")
sc = SparkContext(conf=conf)

# 准备一个RDD
rdd = sc.parallelize(["itheima itcast 666", "itheima itheima itcast", "python itheima"])

# 需求,将RDD数据里面的一个个单词提取出来
rdd2 = rdd.flatMap(lambda x: x.split(" "))
print(rdd2.collect())
# [itheima,itcast,666,itheima,itheima,itcast,python,itheima]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# reduceByKey
  1. 针对KV型RDD,自动按照key分类,然后根据提供的聚合逻辑,完成组内数据的聚合操作
  2. 二元元组
  3. func:(v,v)->v 接受2个传入参数(类型要一致),返回一个返回值,类型和传入要求一致。
"""
演示RDD的reduceByKey成员方法的使用
"""
from pyspark import SparkConf, SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "D:/dev/python/python310/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")
sc = SparkContext(conf=conf)

# 准备一个RDD
rdd = sc.parallelize([('男', 99), ('男', 88), ('女', 99), ('女', 66)])
# 求男生和女生两个组的成绩之和
rdd2 = rdd.reduceByKey(lambda a, b: a + b)
print(rdd2.collect())

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# filter

过滤想要的数据进行保留

"""
演示RDD的filter成员方法的使用
"""
from pyspark import SparkConf, SparkContext
import os

os.environ['PYSPARK_PYTHON'] = "D:/dev/python/python310/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")
sc = SparkContext(conf=conf)

# 准备一个RDD
rdd = sc.parallelize([1, 2, 3, 4, 5])
# 对RDD的数据进行过滤
rdd2 = rdd.filter(lambda num: num % 2 == 0)

print(rdd2.collect())
# 结果是[2,4]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# distinct

对数据去重

"""
演示RDD的distinct成员方法的使用
"""
from pyspark import SparkConf, SparkContext
import os

os.environ['PYSPARK_PYTHON'] = "D:/dev/python/python310/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")
sc = SparkContext(conf=conf)

# 准备一个RDD
rdd = sc.parallelize([1, 1, 3, 3, 5, 5, 7, 8, 8, 9, 10])
# 对RDD的数据进行去重
rdd2 = rdd.distinct()

print(rdd2.collect())
# 输出的结果是:[1,3,5,7,8]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# sortBy
  1. func:(T)->U: 告知按照rdd中的哪个数据进行排序, 比如 lambda x: x[1]表示按照rdd中的第二列进行排序
  2. ascending True升序 False 降序
  3. numPartitions 用多少分区排序 (现在设为1就行)
"""
演示RDD的sortBy成员方法的使用
"""
from pyspark import SparkConf, SparkContext
import os
os.environ['PYSPARK_PYTHON'] = "D:/dev/python/python310/python.exe"
conf = SparkConf().setMaster("local[*]").setAppName("test_spark")
sc = SparkContext(conf=conf)

# 1. 读取数据文件
rdd = sc.textFile("D:/hello.txt")
# 2. 取出全部单词
word_rdd = rdd.flatMap(lambda x: x.split(" "))
# 3. 将所有单词都转换成二元元组,单词为Key,value设置为1
word_with_one_rdd = word_rdd.map(lambda word: (word, 1))
# 4. 分组并求和
result_rdd = word_with_one_rdd.reduceByKey(lambda a, b: a + b)
# 5. 对结果进行排序(按照rdd中的第二列元素进行排序)
final_rdd = result_rdd.sortBy(lambda x: x[1], ascending=True, numPartitions=1)
print(final_rdd.collect())

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 数据输出

输出已经不是RDD类型了

  1. collect:将RDD内容转换为list
  2. reduce:对RDD内容进行自定义聚合
  3. take:取出RDD的前N个元组组成list
  4. count:统计RDD元素个数
# 输出到文本中

调用保存文件的算子,需要配置Hadoop依赖

  1. 下载Hadoop安装包 : 点击下载 (opens new window)
  2. 解压到电脑任意位置
  3. 在Python代码中使用os模块配置:os.environ['HADOOP HOME”]='HADOOP解压文件夹路径
  4. 下载winutils.exe,并放入Hadoop解压文件夹的bin目录内:点击下载 (opens new window)
  5. 下载hadoop.dll,并放入:C:/Windows/system32 文件夹内:点击下载 (opens new window)

# 大数据分布式集群运行

# python高阶技巧

# 闭包

  1. 优点:
    1. 无需定义全局变量即可实现通过函数,持续的访问、修改某个值
    2. 闭包使用的变量的所用于在函数内,难以被错误的调用修改
  2. 缺点:
    1. 由于内部函数持续引用外部函数的值,所以会导致这一部分内存空间不被释放一直占用内存

关键字:用nonlocal关键字修改外部函数的值

# 简单闭包
def outer(logo):
    def inner(msg):
        print(f"<{logo}>{msg}<{logo}>")

    return inner


f1 = outer("测试")
print(type(f1))
f1("内容")

# <class 'function'>
# <测试>内容<测试>

# 使用nonlocal关键字修改外部函数的值
def outer(num1):
    def inner(num2):
        nonlocal num1
        num1 += num2
        print(num1)

    return inner


fn = outer(20)
fn(30)
# 50
fn(30)
# 80

# 案例
def account_create(initial_amount=0):
    def atm(num, deposit=True):
        nonlocal initial_amount
        if deposit:
            initial_amount += num
        else:
            initial_amount -= num
        print(f"现在的余额是:{initial_amount}")

    return atm


fn = account_create()
fn(200, True)
# 现在的余额是:200
fn(100, False)
# 现在的余额是:100
fn(50, True)
# 现在的余额是:150


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

# 装饰器

装饰器其实也是一种闭包,其功能就是在不破坏目标函数原有的代码和功能的前提下为目标函数增加新功能。

# 仅帮助理解,具体使用看下一个举例
# 装饰器的一般写法(闭包)
def outer(func):
    def inner():
        print("我睡觉了")
        func()
        print("我起床了")

    return inner


def sleep():
    import random
    import time
    print("睡眠中......")
    time.sleep(random.randint(1, 5))


fn = outer(sleep)
fn()


# 装饰器的快捷写法(语法糖)
def outer(func):
    def inner():
        print("我睡觉了")
        func()
        print("我起床了")

    return inner


@outer
def sleep():
    import random
    import time
    print("睡眠中......")
    time.sleep(random.randint(1, 5))


sleep()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 设计模式

# 单例模式

  1. 定义:保证一个类只有一个实例,并提供一个访问它的全局访问点
  2. 适用场景:当一个类只能有一个实例,而客户可以从一个众所周知的访问点访问它时。
# str_tools_py 文件
class StrTools:
    pass

str_tool = StrTools()


# test.py文件
from str_tools_py import str_tool

s1 = str_tool
s2 = str_tool

print(id(s1))
print(id(s2))

# 返回一致的地址:
# 2170500775904
# 2170500775904


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 工厂模式

当需要大量创建一个类的实例的时候,可以使用工厂模式。

优点:

  1. 大批量创建对象的时候有统一的入口,易于代码维护
  2. 当发生修改,仅修改工厂类的创建方法即可
"""
演示设计模式之工厂模式
"""

class Person:
    pass

class Worker(Person):
    pass

class Student(Person):
    pass

class Teacher(Person):
    pass


class PersonFactory:
    def get_person(self, p_type):
        if p_type == 'w':
            return Worker()
        elif p_type == 's':
            return Student()
        else:
            return Teacher()


pf = PersonFactory()
worker = pf.get_person('w')
stu = pf.get_person('s')
teacher = pf.get_person('t')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 多线程

  1. 进程:就是一个程序,运行在系统之上,那么便称之这个程序为一个运行进程,并分配进程ID方便系统管理。
  2. 线程: 线程是归属于进程的,一个进程可以开启多个线程,执行不同的工作,是进程的实际工作最小单位。
  3. 操作系统中可以运行多个进程,即多任务运行
  4. 一个进程内可以运行多个线程,即多线程运行
  5. 注意点:
    1. 进程之间是内存隔离的
    2. 线程之间是内存共享的
  6. 并行执行:同一时间做不同的工作
    1. 进程之间就是并行执行的,操作系统可以同时运行好多程序(多任务并行执行)
    2. 线程也可以并行执行(多线程并行执行)

# 多线程编程

import threading 模块 thread = threading.Thread([group[,target[,name[,args[,kwargs]]]]])

  • group:暂时无用,未来功能的预留参数
  • target:执行的目标任务名
  • args:以元组的方式给执行任务传参
  • kwargs:以字典方式给执行任务传参
  • name:线程名,一般不用设置

启动线程: thread.start()

"""
演示多线程编程的使用
"""
import threading


def test1(msg1, msg2):
    print(msg1, msg2)


def test2(msg1):
    print(msg1)


if __name__ == '__main__':
    thread1 = threading.Thread(target=test1, args=("111111", "222222"))
    thread2 = threading.Thread(target=test2, kwargs={"msg1": "333333"})
    thread1.start()
    thread2.start()
    # 111111  222222
    # 333333
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 网络编程

  1. socket
    1. 是进程之间通信一个工具
    2. 2个进程之间通过Socket进行相互通讯,就必须有服务端和客户端
      1. Socket服务端:等待其它进程的连接、可接受发来的消息、可以回复消息
      2. Socket客户端:主动连接服务端、可以发送消息、可以接收回复 image

# 服务端开发

"""
演示Socket服务端开发
"""
import socket
# 创建Socket对象
socket_server = socket.socket()
# 绑定ip地址和端口
socket_server.bind(("localhost", 8888))
# 监听端口
socket_server.listen(1)
# listen方法内接受一个整数传参数,表示接受的链接数量
# 等待客户端链接
# result: tuple = socket_server.accept()
# conn = result[0]        # 客户端和服务端的链接对象
# address = result[1]     # 客户端的地址信息
conn, address = socket_server.accept()
# accept方法返回的是二元元组(链接对象, 客户端地址信息)
# 可以通过 变量1, 变量2 = socket_server.accept()的形式,直接接受二元元组内的两个元素
# accept()方法,是阻塞的方法,等待客户端的链接,如果没有链接,就卡在这一行不向下执行了

print(f"接收到了客户端的链接,客户端的信息是:{address}")

while True:
    # 接受客户端信息,要使用客户端和服务端的本次链接对象,而非socket_server对象
    data: str = conn.recv(1024).decode("UTF-8")
    # recv接受的参数是缓冲区大小,一般给1024即可
    # recv方法的返回值是一个字节数组也就是bytes对象,不是字符串,可以通过decode方法通过UTF-8编码,将字节数组转换为字符串对象
    print(f"客户端发来的消息是:{data}")
    # 发送回复消息
    msg = input("请输入你要和客户端回复的消息:")
    if msg == 'exit':
        break
    conn.send(msg.encode("UTF-8"))
# 关闭链接
conn.close()
socket_server.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

实现服务端并结合客户端进行测试: 点击下载网络调试助手作为客户端 (opens new window)

# 客户端开发

"""
演示Socket客户端开发
"""
import socket
# 创建socket对象
socket_client = socket.socket()
# 连接到服务端
socket_client.connect(("localhost", 8888))

while True:
    # 发送消息
    msg = input("请输入要给服务端发送的消息:")
    if msg == 'exit':
        break
    socket_client.send(msg.encode("UTF-8"))
    # 接收返回消息
    recv_data = socket_client.recv(1024)        # 1024是缓冲区的大小,一般1024即可。 同样recv方法是阻塞的
    print(f"服务端回复的消息是:{recv_data.decode('UTF-8')}")
# 关闭链接
socket_client.close()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 正则表达式

# match、search、findall

"""
演示Python正则表达式re模块的3个基础匹配方法
"""
import re

# match 从头匹配
s = "1python itheima python python"
result = re.match("python", s)
print(result)
# None
s = "python itheima python python"
# print(result.span())
# (0,6)
# print(result.group())
# python

# search 搜索匹配
s = "1python itheima python python"
result = re.search("python2", s)
print(result)
# None

# findall 搜索全部匹配
s = "1python itheima python python"
result = re.findall("python", s)
print(result)
# ['python', 'python', 'python']
# 返回空 list:[]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

# 元字符匹配

字符 功能
. 匹配任意1个字符(除了\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 匹配非单词边界
分组匹配
字符 功能
() 将括号中字符作为一个分组
import re

s = "itheima1 @@python2 !!666 ##itccast3"
result = re.findall(r'[b-eF-Z3-9]', s)   # 字符串前面带上r的标记,表示字符串中转义字符无效,就是普通字符的意思
print(result)
# ['e', '6', '6', '6', 'c', 'c', '3']

# 匹配账号,只能由字母和数字组成,长度限制6到10位
r = '^[0-9a-zA-Z]{6,10}$'
# ^ $ 表示从头匹配到尾
s = '123456'
print(re.findall(r, s))
# ['123456']

r = '^[0-9a-zA-Z]{6,10}$'
s = '123456_'
print(re.findall(r, s))
# []

r = '[0-9a-zA-Z]{6,10}'
# ^ $ 表示从头匹配到尾
s = '123456 233334'
print(re.findall(r, s))
# ['123456', '233334']

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 递归

方法(函数)自己调用自己的一种特殊编程写法

def func():
   if ...:
      func()
   return ...
1
2
3
4
"""
演示Python递归操作
需求:通过递归,找出一个指定文件夹内的全部文件

思路:写一个函数,列出文件夹内的全部内容,如果是文件就收集到list
如果是文件夹,就递归调用自己,再次判断。

"""
import os


def test_os():
    """演示os模块的3个基础方法"""
    print(os.listdir("D:/test"))        # 列出路径下的内容
    # print(os.path.isdir("D:/test/a"))   # 判断指定路径是不是文件夹
    # print(os.path.exists("D:/test"))    # 判断指定路径是否存在


def get_files_recursion_from_dir(path):
    """
    从指定的文件夹中使用递归的方式,获取全部的文件列表
    :param path: 被判断的文件夹
    :return: list,包含全部的文件,如果目录不存在或者无文件就返回一个空list
    """
    print(f"当前判断的文件夹是:{path}")
    file_list = []
    if os.path.exists(path):
        for f in os.listdir(path):
            new_path = path + "/" + f
            if os.path.isdir(new_path):
                # 进入到这里,表明这个目录是文件夹不是文件
                file_list += get_files_recursion_from_dir(new_path)
            else:
               file_list.append(new_path)
    else:
        print(f"指定的目录{path},不存在")
        return []

    return file_list

if __name__ == '__main__':
   # 递归方法示例
   print(get_files_recursion_from_dir("D:/test"))


def a():
    a()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

# python写api接口

# 框架介绍

  1. Django REST framework (DRF): 作为Django的扩展,DRF是一个功能强大且灵活的框架,专注于构建RESTful API。它提供了序列化、认证、权限管理等功能,适用于中大型项目。
  2. Flask-RESTful: 基于Flask的扩展,提供了简化RESTful API构建的工具。它注重简洁性,适用于小型到中型的项目。 以上可以了解一下

具体文档请跳转: Django

Last Updated: 4/4/2024, 2:01:18 PM