python基础

  • 装饰器,有那些,应用场景,如何使用?
  • 迭代器 生成器 的概念和应用场景
  • 深浅拷贝
  • 闭包
  • 多线程;多线程的优缺点; 线程进程区别 避免死锁 ; 线程的新建、停止 ;线程池有哪几种。固定长度, 如果超出了是什么情况。线程阻塞。
  • 网络编程
  • 各个数据结构的特点 常用方法
  • 列表生成式 字典生成式 lambal 表达式
  • 可变参数,应用场景
  • 面向对象的三大特征
  • return yield的区别
  • 私有变量能否访问
  • 类的方法种类和区别
  • 类变量,实例变量,类对象,实例对象的区别
  • dict json怎么相互转换

PEP8编码规范
前闭后开
列表转换为字符串join

a = ["a", "p", "p", "l", "e"]
# 将列表中的每一个元素拼接起来
print("".join(a))
# apple

字符串转换为列表split

# 根据split内的内容将字符串进行切分
str1 = "apple banner"
str1.split(" ")
# ['apple', 'banner']

in 如果在指定的序列中找到值返回 True,否则返回 False。 not in
is 是判断两个标识符是不是引用自一个对象 is not

list_a = ["a", "b", "c"]
list_b = ["a", "b", "c"]

print(id(list_a)) # 使用id查看变量的内存地址
print(id(list_b))
print(list_a is list_b)
print(list_a == list_b)

可变的数据结构,即使看着一样,但内存地址是不同的
不可变的数据结构,看着一样,内存地址是相同的

h = "变量1" if a>b else "变量2"

break-跳出整个循环体
continue:跳出当前轮次循环
列表推导式

li = [i for i in range(11)]
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
li1 = [i for i in range(11) if i % 2 == 0]
# [0, 2, 4, 6, 8, 10]
列表方法 作用 入参 返回
append() append(item):将一个对象 item 添加到列表的末尾。 入参:对象 item 返回:None
extend() extend(iterable):将一个可迭代对象的所有元素,添加到列表末尾。 入参:可迭代对象 iterable 返回:None
insert() insert(index, item):将一个对象插入到指定的索引位置 入参:索引值 index ,一个对象 item 返回:None 原索引位置及后面的元素后移一位
pop() pop(index) 或 pop() 入参:索引值 index,可不传 弹出并返回所指定索引的元素。返回:指定索引的元素、返回:未指定索引则返回末尾元素 如果索引值不正确,或者列表已经为空,则引发 IndexError 错误
remove() remove(item)移除列表中第一个等于 item 的元素 入参:指定元素 item 返回:None 目标元素必须已存在,否则会报 ValueError
sort() sort(key=None, reverse=False)对列表进行原地排序,只使用 < 来进行各项间比较。 key:指定带有一个参数的函数,用于从每个列表元素中提取比较键。reverse:默认值为 False 表示升序,为 True 表示降序 返回:None
reverse() reverse():将列表中的元素顺序反转 参数:无 返回:None 反转只是针对索引值,元素之间不相互比较
元组方法 作用 入参 返回
index() index(item)查找元组中的元素 入参:对象 item 返回与目标元素相匹配的首个元素的索引。 目标必须在元组中存在的,否则会报错
count() count(item):返回某个元素出现的次数。 入参:对象 item 返回:次数
a, b, c = (1, 2, 3)
print(type(a),a)
#  1
a= (1,)
print(type(a),a)
print(type(*a),*a)
#  (1,)
#  1
集合方法 作用 入参 返回
add() add(item):将单个对象添加到集合中 入参:对象 item 返回:None
update() update(iterable)批量添加来自可迭代对象中的所有元素 入参:可迭代对象 iterable 返回:None
remove() remove(item):从集合中移除指定元素 item。 入参:指定元素值 返回:None 如果 item 不存在于集合中则会引发 KeyError
discard() discard(item):从集合中移除指定对象 item。 入参:指定对象值 返回:None 元素 item 不存在没影响,不会抛出 KeyError 错误。
pop() pop():随机从集合中移除并返回一个元素。 入参:无。 返回:被移除的元组。 如果集合为空则会引发 KeyError。
clear() clear():清空集合,移除所有元素 入参:无 返回:None
集合运算 函数 操作符
交集运算 intersection() 操作符:& python基础_第1张图片
并集运算 union() 操作符:| python基础_第2张图片
差集运算 difference() 操作符: - python基础_第3张图片
字典方法 作用 入参 返回
keys() 入参:无 返回由字典键组成的一个新视图对象。
values() 入参:无 返回由字典值组成的一个新视图对象。
items() 入参:无 返回由字典项 ((键, 值) 对) 组成的一个新视图对象。
get() get(key)获取指定 key 关联的 value 值。 key:字典的键,必传。 如果 key 存在于字典中,返回 key 关联的 value 值。如果 key 不存在,则返回 None 此方法的好处是无需担心 key 是否存在,永远都不会引发 KeyError 错误。
update() update(dict)使用来自 dict 的键/值对更新字典,覆盖原有的键和值。 入参:字典对象,必传 返回:None
pop() pop(key)删除指定 key 的键值对,并返回对应 value 值。 key:必传 如果 key 存在于字典中,则将其移除并返回 value 值、如果 key 不存在于字典中,则会引发 KeyError。

列表变字典

list1 = [("name", "Harry Potter"), ("age", 18)]
dict1 = {i: j for i, j in list1}
# {'name': 'Harry Potter', 'age': 18}

字典变列表

params = {'Tom':18, 'Jim':20, 'Lily':12}
dictlist=[]
for keys, value in params.items():
    temp = (keys,value)
    dictlist.append(temp)
print(dictlist)
dc = {'a': 1, 'b': 2, 'c': 3}
d_new = {k : v ** 2 for k,v in dc.items() if v > 1 }
print(d_new)
# {'b': 4, 'c': 9}

内置函数

*args 接收任意多个实际参数,并将其放到一个元组中。

使用已经存在的列表或元组作为函数的可变参数,可以在列表的名称前加*号

def print_language(*args):
    print(args)
    for i in args:
        print(i)

print_language("python", "java", "php", "go")
params = ["python", "java", "php", "go"]
print_language(*params)# 解包

**kwargs接收任意多个类似关键字参数一样显式赋值的实际参数,并将其放到一个字典中

使用已经存在字典作为函数的可变参数,可以在字典的名称前加**

def print_info(**kwargs):
    print(kwargs)

print_info(Tom=18, Jim=20, Lily=12)
params = {'Tom':18, 'Jim':20, 'Lily':12}
print_info(**params)

匿名函数-没有名字的函数-lambda

  • 需要一个函数,但是又不想费神去命名这个函数
  • 通常在这个函数只使用一次的场景下
  • 可以指定短小的回调函数
result = lambda [arg1 [, arg2, .... , argn]]: expression

result:调用 lambda 表达式
[arg1 [, arg2, …. , argn]]:可选,指定要传递的参数列表
expression:必选,指定一个实现具体功能的表达式

dictlist=[('Tom', 18), ('Jim', 20), ('Lily', 12)]
# lambda x:x[1] 返回了列表中每个元组的第二个元素
dictlist.sort(key=lambda x:x[1])
# [('Lily', 12), ('Tom', 18), ('Jim', 20)]

类的方法:实例方法(构造方法)、类方法、静态方法

构造方法:实例化对象__init__(self,参数) 实例变量(实例属性)self.name
实例方法:在类中定义的函数 def 方法名(self,参数)
类方法:使用 @classmethod 装饰器 def 方法名(cls,参数) 操作获取类的详细状态或属性——不修改原有代码,进行拓展的方式
静态方法:使用 @staticmethod 装饰器 def 方法名(参数) 不能访问类的数据 ——此方法没有任何和实例、类相关的部分,可以作为一个独立函数使用,通用的工具函数,将常用的函数放在一个类中进行管理

内置类装饰器:不用实例化、直接调用、提升代码的可读性

普通方法
定义:第一个参数为self,代表 实例本身
调用:要有实例化的过程,通过 实例对象.方法名 调用

类方法classmethod
定义:使用 @classmethod 装饰器,第一个参数为类本身,所以通常使用cls命名做区分(非强制),在类内可以直接使用类方法或类变量,无法直接使用实例变量或方法
调用:无需实例化,直接通过 类.方法名 调用,也可以通过 实例.方法名 调用

静态方法staticmethod
定义:使用 @staticmethod 装饰器,没有和类本身有关的参数,无法直接使用任何类变量、类方法或者实例方法、实例变量
调用:无需实例化,直接通过 类.方法名 调用,也可以通过 实例.方法名 调用

名称 定义 调用 关键字 使用场景
普通方法 至少需要一个参数self 实例名.方法名() 方法内部涉及到实例对象属性的操作
类方法 至少需要一个cls参数 类名.方法名() 或者实例名.方法名() @classmethod 如果需要对类属性,即静态变量进行限制性操作
静态方法 无默认参数 类名.方法名() 或者实例名.方法名() @staticmethod 无需类或实例参与
class DateFormat:
    def __init__(self, year=0, month=0, day=0):
        self.year = year
        self.month = month
        self.day = day

    def out_date(self):
        return f"输入的时间为{self.year}年,{self.month}月,{self.day}日"

    @classmethod
    def json_format(cls,json_data):
        year, month, day = json_data["year"],json_data["month"],json_data["day"]
        return cls(year, month, day)

year, month, day = 2017, 7, 1
demo = DateFormat(year, month, day)
print(demo.out_date())

#需求变更,输入 年、月、日 的格式为json,不修改构造函数的前提下,更改代码:添加类方法json_format
data={"year":2022,"month":6,"day":27}
demo_json = DateFormat.json_format(data)
print(demo_json.out_date())

参数类型
name:str
参数:类型
返回类型
def get_name(name:str) -> str:

类型提示 的好处:增强代码可读性;ide中代码提示;静态代码检查(第三方库)
类型别名:Vector = List[float]

from typing import List
Vector = List[float]

def scale(scalar:float,vector:Vector) ->Vector:
    return [scalar *num for num in vector]
print(scale(2, [1.1, 2.2, 3.3, 4.4]))
# [2.2, 4.4, 6.6, 8.8]

自定义类型

class Student:
    name :str
    age :int 
def get_student(name:str) ->Student:
    return Student()

安装pip install mypy
命令行执行mypy xx.py

python基础_第4张图片
package
module——py文件
function

import 模块名
from 模块名 import 方法、变量、类
from 模块名 import *

系统内置模块
第三方开源模块
自定义模块

dir() 找出当前模块定义的对象
dir(sys) 找出参数sys模块定义的对象

封装

隐藏:属性和实现细节,不允许外部直接访问
暴露:公开方法,实现对内部信息的操作和访问

作用:限制安全的访问和操作,提高数据安全性;可进行数据检查,从而有利于保证对象信息的完整性。

内部属性
_属性名
私有属性
__属性名 == _类名__属性名

class TestDome:
    name = "Tom"
    _username = "username"
    __password = "password"

    @property
    # 计算属性,把一个方法变成属性
    def password(self):
        return self.__password

    # 使用@计算属性名。setter装饰器
    @password.setter
    def password(self,value):
        if len(value) >= 6:
            self.__password = value
        else:
            print("密码长度不足")

obj = TestDome()
# 访问私有属性
print(obj.password)
# 修改私有属性
obj.password = "admin123"
print(obj.password)
# 修改私有属性
obj.password = "123"
print(obj.password)

#print(TestDome.__dict__)

继承

复用父类的公开属性和方法,拓展出新的属性和方法。
class 类名(父类列表)
默认父类object

isinstance(实例,类名) 检查对象是否是某个类及其派生类的实例
issubclass(类名1,类名2)检查类名1是否是类名2的子类

多态

同名方法呈现多种行为
举例 +号: 加法(数字+数字)拼接(字符串+字符串)合并(列表+列表)
举例 len()函数:获取可迭代对象的长度或个数, 可以接收字符串、可以接收列表,入参不同
举例 同名变量调用 同名方法呈现多种行为

class China:
    def speak(self):
        print("说汉语")

class Usa:
    def speak(self):
        print("say english")

cn = China()
us = Usa()

for x in (cn,us):
    x.speak()

多态 与继承
方法重写:子类的方法名称与父类的相同(优先访问自己的方法,父类同名方法被覆盖)
重写构造方法,两种super().init() 父类名.init(self)

class Human:
    message = "人类"
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def live(self):
        print("住在地球上")

class Student(Human):
    def __init__(self,name ,age,school):
        # super().__init__(name,age)
        Human.__init__(self,name,age)
        self.school = school
    def live(self):
        print(f"住在{self.school}里")

stu = Student("Tom",10,"希望小学")
print(stu.name)
stu.live()
#Tom 住在希望小学里

错误:语法错误SyntaxError、逻辑错误、系统错误
异常:程序执行过程中出现的未知错误;语法和逻辑正常;程序业务逻辑不完善引起的程序漏洞bug

ZeroDivisionError除数为零异常
NameError名称异常
IndexError索引异常
KeyError键异常
ValueError值异常

try:
    li = [2]
    print(li[9])
except Exception as e:
    print(e)
    print("发生异常时执行的代码")
else:
    print("没有异常时执行的代码")
finally:
    print("最终都会被执行,无论有无异常")

抛出异常

def set_age(age:int):
    if age <= 0 or age > 150:
        raise ValueError(f"年龄的值错误:{age}")
    else:
        print(f"年龄是{age}")

set_age(-1)

自定义异常

class MyException(Exception):
    def __init__(self,msg):
        print(f"这是一个异常:{msg}")

def set_age(age: int):
    if age <= 0 or age > 150:
        raise MyException(f"年龄的值错误:{age}")
    else:
        print(f"年龄是{age}")
set_age(-2)

程序调试:修正语法错误、逻辑错误的过程
打印、日志 、debug

import logging
logging.basicConfig(level=logging.INFO)
logging.info("sdsds")

内置库 os

operating system
系统相关操作,处理文件、目录…

import os
# 查看说明文档
help(os)
# 查看所有属性和方法名称
print(dir(os))

os.name:获取系统名称,nt代表Windows,posix代表linux
os.environ:获取系统环境变量信息
os.getenv(‘PATH’):获取指定名称的环境变量信息
os.system():执行系统指令,模拟cmd指令

os.getcwd():获取当前目录
os.chdir():切换目录,cd命令
os.listdir():列出当前目录内容
os.mkdir():创建空目录
os.makedirs():递归创建多级目录
os.rmdir():删除空目录
os.rename():重命名目录
os.remove():删除文件

os.path.abspath(path) 返回绝对路径os.path.abspath(file)
os.path.basename(path) 返回文件名
os.path.dirname(path) 返回文件路径
os.path.split(path) 分割路径
os.path.join(path) 拼接路径
os.path.exists(path) 判断路径是否存在
os.path.isdir(path) 判断是否是目录
os.path.isfile(path) 判断是否是文件
os.path.getsize(path) 获取文件大小,单位是字节

内置库 sys

与python解释器交互
sys.version:返回 Python 解释器版本
sys.platform:返回操作系统平台名称
sys.argv:返回外部向程序传递的参数
sys.modules:返回已导入的模块信息
sys.path:返回导包的搜索路径列表

sys.getdefaultencoding():获取编码方式
sys.exit():运行时退出

import sys,time
for i in range(10):
    if i == 6:
        print("exit...")
        sys.exit("正常退出")
    print(f"running {i} ...")
    time.sleep(1)

内置库 文件处理

python基础_第5张图片
打开文件、操作文件(读写追加)、关闭文件
def open(file, mode=‘r’, buffering缓冲区大小=None, encoding=None, errors=None, newline换行符=None, closefd=True):
r 只读 ,r+ 读 写,替换原来的内容,覆盖原有内容,如果内容很少,就只会覆盖一部分
w 写入 , w+ 读 写,没有文件时新建文件,清空内容再写入
a 追加 , a+ 读 写,追加内容
b 二进制(音乐、视频…)

f = open('demo.txt','r',encoding='utf-8')
print(f.read())
f.close()

python基础_第6张图片
忘记关闭文件的危害:打开文件达到一定数量将会导致打开失败;占用内存空间,非常浪费资源;会导致系统自动回收资源,而丢失数据。
with 自动关闭文件

with open('demo.py','r',encoding='utf-8') as f:
    print(f.read())

内置库 math

数字常熟
python基础_第7张图片

数论与表示函数
python基础_第8张图片

幂对数函数
python基础_第9张图片

三角对数函数
python基础_第10张图片

高等特殊函数
python基础_第11张图片

内置库 日期与时间处理

日志信息里需要时间;计算某个功能的执行时间;用日期命名文件;生成随机数…
time
datatime
calendar
时间戳:浮点数
格式化的时间字符串

  • 获取当前时间
  • 获取特定时间
  • datatime 与 timestamp 时间戳互转
  • datatime 与 str 互转
import datetime
nowtime = datetime.datetime.now()
print(nowtime)# 2022-06-28 10:24:45.959896
print(nowtime.day)# 28
print(nowtime.timestamp())# 1656383085.959896
old_time = datetime.datetime(2011,6,2,10,15)
print(old_time)# 2011-06-02 10:15:00
str0 = old_time.strftime('%a, %b %d %H:%M')
print(str0)# Thu,Jun 02 10:15
str1 = "2011-06-02 10:15:00"
time1 = datetime.datetime.strptime(str1,"%Y-%m-%d %H:%M:%S")
print(time1)# 2011-06-02 10:15:00

time2 = datetime.datetime.fromtimestamp(nowtime.timestamp())
print(time2)# 2022-06-28 10:27:27.995164

内置库 json

JSON 是用于存储和交换数据的语法,是一种轻量级的数据交换格式。
使用场景:接口数据传输、序列化、配置文件
python基础_第12张图片
可以从字符串或文件中解析 JSON,该库解析 JSON 后将其转为 Python 字典或者列表

dumps():将 Python 对象编码成 JSON 字符串
loads():解码 JSON 字符串数据,该函数返回 Python 对象
dump(): Python 对象编码,并将数据写入 json 文件中
load():从 json 文件中读取数据并解码为 Python 对象

import json

with open("./demo.json") as f:
    data:dict = json.loads(f.read())

dumps 常用参数
indent:根据数据格式缩进显示,默认为 None,没有缩进
ensure_ascii:对中文使用 ASCII 编码,默认为 True

内置库 正则表达式 re

正则表达式:记录文本规则的代码,可以查找操作符合某些复杂规则的字符串
作用:处理字符串\处理日志
把正则表达式作为模式字符串,正则表达式可以使用原生字符串来表示,原生字符串需要在字符串前方加上 r’string’

正则表达式对象转换
compile():将字符串转换为正则表达式对象,需要多次使用这个正则表达式的场景

import re
'''
prog:正则对象,可以直接调用匹配、替换、分割的方法,不需要再传入正则表达式
pattern:正则表达式
'''
pattern = r"apple"
prog = re.compile(pattern)

匹配字符串
re.match():从字符串的开始处进行匹配
re.search():在整个字符串中搜索第一个匹配的值
re.findall():在整个字符串中搜索所有符合正则表达式的字符串,返回列表

'''
pattern: 正则表达式
string: 要匹配的字符串
flags: 可选,控制匹配方式
    - A:只进行 ASCII 匹配
    - I:不区分大小写
    - M:将 ^ 和 $ 用于包括整个字符串的开始和结尾的每一行
    - S:使用 (.) 字符匹配所有字符(包括换行符)
    - X:忽略模式字符串中未转义的空格和注释
'''
re.match(pattern, string, [flags])
re.search(pattern, string, [flags])
re.findall(pattern, string, [flags])
import re
pattern = r"apple"
s1  = "Apple is a fruit"
match1 = re.match(pattern,s1,re.I)
print(match1)# 
print(f"匹配起始位置:{match1.start()},结束位置:{match1.end()}")
print(f"匹配位置:{match1.span()}")
print(f"要匹配的字符串:{match1.string},匹配到的数据:{match1.group()}")
import re
pattern = r"apple"
s1  = "Apple is a fruit"
match1 = re.match(pattern,s1,re.I)
print(match1)# 
print(f"匹配起始位置:{match1.start()},结束位置:{match1.end()}")
print(f"匹配位置:{match1.span()}")
print(f"要匹配的字符串:{match1.string},匹配到的数据:{match1.group()}")

re.sub():实现字符串替换

'''
pattern:正则表达式
repl:要替换的字符串
string:要被查找替换的原始字符串
count:可选,表示替换的最大次数,默认值为 0,表示替换所有匹配
flags:可选,控制匹配方式
'''
re.sub(pattern, repl, string, [count], [flags])

re.split():根据正则表达式分割字符串,返回列表

'''
pattern:正则表达式
string:要匹配的字符串
maxsplit:可选,表示最大拆分次数
flags:可选,控制匹配方式
'''
re.split(pattern, string, [maxsplit], [flags])

内置库 多线程 threading26

线程:小丑扔一个苹果
多线程:小丑扔三个苹果,3个线程轮巡执行,谁也不会在空中多停留一会儿
GIL 在同一时刻,只能有一个线程在运行
并发
排队,线程一执行完,再执行线程二,本质跟一个线程一样(如果有sleep)
信息交互方便,高效,资源切换比较快
flask

import threading
def task():
    print("扔第二个苹果")
def task2():
    print("扔第三个苹果")
def main():
    print("扔第一个苹果")
    #     创建线程
    thread1 = threading.Thread(target=task)
    # 执行线程
    thread1.start()
    thread2 = threading.Thread(target=task2)
    thread2.start()

if __name__ == '__main__':
    main()

多进程:3个小丑扔苹果,3个苹果同时在空中,但每个小丑的苹果不方便通讯,慢
并行
应用场景:cpu大量计算,cpu逻辑处理器

import datetime
import threading
from time import sleep


def task():
    sleep(3)
    print("扔第二个苹果")
def task2():
    sleep(5)
    print("扔第三个苹果")
def main():
    start_time = datetime.datetime.now()
    print(start_time)
    print("扔第一个苹果")
    thread1 = threading.Thread(target=task)
    thread2 = threading.Thread(target=task2)
    thread1.start()
    thread2.start()
    # 让其他线程等待自己执行完成
    thread1.join()
    thread2.join()
    end_time = datetime.datetime.now()
    print(end_time)

if __name__ == '__main__':
    main()

内置库 logging

https://docs.python.org/zh-cn/3/howto/logging.html
日志作用:调试;辅助定位;数据分析
python基础_第13张图片
python基础_第14张图片
python基础_第15张图片

import logging

# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)

# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)

# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

# add formatter to ch
ch.setFormatter(formatter)

# add ch to logger
logger.addHandler(ch)

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')
[loggers]
keys=root,main

[handlers]
keys=consoleHandlers,fileHandlers

[formatters]
keys=fmt

[logger_root]
level=DEBUG
handlers=consoleHandlers,fileHandlers

[logger_main]
level = DEBUG
handlers = fileHandlers
qualname=main
propagate=0

[handler_consoleHandlers]
class = StreamHandler
level = DEBUG
formatter = fmt
args = (sys.stdout,)

[handler_fileHandlers]
class = logging.handlers.RotatingFileHandler
level = DEBUG
formatter = fmt
args = ('./logs/test.log', 'a', 10000, 3, 'UTF-8')

[formatter_fmt]
format=%(asctime)s (%(filename)s:%(lineno)s) [%(levelname)s] %(message)s

import logging.config

logging.config.fileConfig('logging.conf')

# create logger
logger = logging.getLogger('main')

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

pip

https://pypi.org/ 托管了大量流行的 Python 包

查看 pip 版本 pip -V
查看帮助文档 pip help
查看包列表 pip list
导出包列表 pip freeze
安装 pip install 包名
升级 pip install -U 包名
卸载 pip uninstall 包名

pip install -U pytest
升级已安装的 Python 包
pip install -i 镜像源

阿里源:https://mirrors.aliyun.com/pypi/simple/
清华源:https://pypi.tuna.tsinghua.edu.cn/simple/
豆瓣源:http://pypi.douban.com/simple/
使用镜像
pip install pytest -i https://pypi.douban.com/simple

venv

venv 虚拟环境的优点:独立的 Python 环境,不会产生冲突;有助于包的管理;删除和卸载方便。
venv 使用方法:创建虚拟环境;激活虚拟环境;安装 Python 包。

  • venv 创建虚拟环境
    python3 -m venv test

  • venv 激活虚拟环境
    切换指定文件夹
    Windows:/Scripts/
    macOS:/bin/
    执行指令:activate

# Windows 系统激活虚拟环境
cd test
cd Scripts
activate

# macOS系统激活虚拟环境
cd test
cd bin
source actiavte
# 或者一步到位
source ./test/bin/acitvate
  • 退出虚拟环境:deactivate

常用第三方库 yaml

一种数据序列化格式,用于人类的可读性和与脚本语言的交互,一种被认为可以超越 XML、JSON 的配置文件。
YAML 基本语法规则:大小写敏感;使用缩进表示层级关系;缩进时不允许使用 Tab 键,只允许使用空格;缩进的空格数目不重要,只要相同层级的元素左侧对齐即可;#表示注释,从这个字符一直到行尾都被注释掉了

对象:键值对的集合,用冒号 “:” 表示
数组:一组按次序排列的值,前加 “-”
纯量:单个的、不可再分的值,字符串、布尔值、整数、浮点数、Null、时间、日期

Python 的 YAML 解析器和生成器
官网:https://pypi.org/project/PyYAML/
安装:pip install pyyaml

创建 yaml 文件

import yaml

data = {
    "client": {"default-character-set": "utf8"},
    "mysql": {"user": 'root', "password": 123},
    "custom": {
        "user1": {"user": "张三", "pwd": 666},
        "user2": {"user": "李四", "pwd": 999},
    }
}
# 直接 dump 可以把对象转为 YAML 文档
with open('./my.yaml', 'w', encoding='utf-8') as f:
    yaml.dump(data, f, allow_unicode=True)

读取 yaml 文件

import yaml

file_path = './my.yaml'

with open(file_path, 'r', encoding='utf-8') as f:
    data = yaml.safe_load(f)
print(data)

常用第三方库 pymysql

Python 的数据库接口标准是 Python DB-API
PyMySQL 是从 Python 连接到 MySQL 数据库服务器的接口
PyMySQL 的目标是成为 MySQLdb 的替代品
官方文档:http://pymysql.readthedocs.io/

host:MySQL 服务器地址
user:用户名
password:密码
database:数据库名称
charset:编码方式,推荐使用 utf8mb4

import pymysql

# 1.封装建立连接的对象
def get_conn():
    conn = pymysql.connect(
        host="服务器地址",
        user="root",
        password="123456",
        database="数据库名",
        charset="utf8mb4"
    )
    return conn
    
from . import get_conn

def test_demo():
    # 1.获取连接对象
    conn = get_conn()
    # 2.获取游标对象
    cursor = conn.cursor()
    # 3.执行SQL
    cursor.execute("SELECT VERSION();")
    # 4.查询结果
    version = cursor.fetchone()
    print(f"数据库的版本是:{version}")
    # 5.关闭连接
    conn.close()

CRUD 操作:
创建表
插入记录
查询记录
更新记录
删除记录
执行事务:
提交:commit
回滚:rollback

pymysql 创建表

from . import get_conn

def test_create():
    conn = get_conn()  # 获取连接
    cursor = conn.cursor()  # 获取游标

    sql = """
    CREATE TABLE `testcase` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `title` varchar(255) COLLATE utf8_bin NOT NULL,
    `expect` varchar(255) COLLATE utf8_bin NOT NULL,
    `owner` varchar(255) COLLATE utf8_bin NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
    """
    cursor.execute(sql)  # 执行SQL
    conn.close()  # 关闭连接

pymysql 插入操作

from . import get_conn

def test_insert():
    conn = get_conn()  # 获取连接
    cursor = conn.cursor()  # 获取游标
    sql = """INSERT INTO testcase
    (id, title, expect, owner)
    values (1, 'S11总决赛', '冠军', 'EDG');
    """
    cursor.execute(sql)  # 执行SQL
    conn.commit()  # 提交

执行事务

from . import get_conn

def test_insert():
    conn = get_conn()  # 获取连接
    cursor = conn.cursor()  # 获取游标
    sql = """INSERT INTO testcase
    (id, title, expect, owner)
    values (2, 'S11全球总决赛', '冠军', 'EDG');
    """
    try:
        cursor.execute(sql)  # 执行SQL
        conn.commit()  # 提交事务
    except:
        conn.rollback()  # 回滚事务
    finally:
        conn.close()  # 关闭连接

pymysql 查询操作
fetchone():获取单条记录
fetchmany(n):获取 n 条记录
fetchall():获取所有结果记录

import sys
from . import get_conn

def test_retrieve():
    conn = get_conn()  # 获取连接
    cursor = conn.cursor()  # 获取游标
    sql = "SELECT * FROM testcase;"
    # 捕获异常
    try:
        cursor.execute(sql)  # 执行SQL
        record = cursor.fetchone()  # 查询记录
        print(record)
    except Exception as e:
        print(sys.exc_info())  # 打印错误信息
    finally:
        conn.close()  # 关闭连接

pymysql 更新操作

from . import get_conn

def test_update():
    conn = get_conn()
    cursor = conn.cursor()
    sql = "UPDATE testcase SET owner='hogwarts' WHERE id=2;"
    try:
        cursor.execute(sql)  # 执行SQL
        conn.commit()  # 提交事务
    except:
        conn.rollback()  # 回滚事务
    finally:
        conn.close()  # 关闭连接

pymysql 删除操作

from . import get_conn

def test_delete():
    conn = get_conn()  # 获取连接
    cursor = conn.cursor()  # 获取游标
    sql = "DELETE FROM testcase WHERE id=3;"
    try:
        cursor.execute(sql)  # 执行SQL
        conn.commit()  # 提交事务
    except:
        conn.rollback()  # 回滚事务
    finally:
        conn.close()  # 关闭连接

常用第三方库 urllib3

发起网络请求:内置模块urllib第三方库requests、urllib3
线程安全;连接池管理;客户端 SSL/TLS 验证;支持 HTTP 和 SOCKS 代理
官方文档:https://urllib3.readthedocs.io/en/stable/

import urllib3

def test_response():
    # 创建连接池对象
    pm = urllib3.PoolManager()
    # 发送请求
    resp = pm.request(method='GET', url="http://httpbin.org/ip")
    print(type(res))
    print(resp.status)  # 查看响应状态状态码
    print(resp.headers)  # 查看响应头信息
    print(resp.data)  # 查看响应原始二进制信息

二进制响应内容解码,成JSON 字符串

import urllib3
import json

def test_response():
    pm = urllib3.PoolManager()
    resp = pm.request(method='GET', url="http://httpbin.org/ip")
    # 获取二进制形式的响应内容
    raw = resp.data
    print(type(raw), raw)
    # 使用utf-8解码成JSON字符串
    content = raw.decode('utf-8')
    print(type(content), content)
    # 将JSON字符串解析成字典对象
    dict_obj = json.loads(content)
    print(type(dict_obj), dict_obj)
    print(dict_obj['origin'])

语法:request(method, url, fields, headers, **)
必填
method:请求方式
url:请求地址
选填
headers:请求头信息
fields:请求体数据
body:指定请求体类型
tiemout:设置超时时间

import urllib3
import json

def test_headers():
    pm = urllib3.PoolManager()
    url = "http://httpbin.org/get"
    # 定制请求头
    headers = {'School': 'hogwarts'}
    resp = pm.request('GET', url, headers=headers)

定制查询字符串参数
fields 参数:适用于GET, HEAD, DELETE 请求
拼接url:适用于POST, PUT请求

import urllib3
import json

# GET/HEAD/DELETE 请求
def test_fields():
    pm = urllib3.PoolManager()
    url = "http://httpbin.org/get"
    fields = {'school': 'hogwarts'}
    resp = pm.request(method='GET', url=url, fields=fields)

# POST/PUT 请求
def test_urlencode():
   # 从内置库urllib的parse模块导入编码方法
    from urllib.parse import urlencode
    pm = urllib3.PoolManager()
    url = "http://httpbin.org/post"
    # POST和PUT请求需要编码后拼接到URL中
    encoded_str = urlencode({'school': 'hogwarts'})
    resp = pm.request('POST', url=url+"?"+encoded_str)

提交 form 表单数据
类型 ‘Content-Type’: 'multipart/form-data
请求方式:POST、PUT

import urllib3
import json

# POST/PUT 请求
def test_form():
    pm = urllib3.PoolManager()
    url = "http://httpbin.org/post"
    fields = {'school': 'hogwarts'}
    # fields数据会自动转成form格式提交
    resp = pm.request('POST', url, fields=fields)

提交 JSON 格式数据
类型:‘Content-Type’: ‘application/json’
请求方式:POST、PUT

import urllib3
import json

def test_json():
    pm = urllib3.PoolManager()
    url = "http://httpbin.org/post"
    # 设定请求体数据类型
    headers={'Content-Type': 'application/json'}
    # JSON文本数据
    json_str = json.dumps({'school': 'hogwarts'})
    resp = pm.request('POST', url, headers=headers, body=json_str)

timeout :设置超时时间
时间单位:秒
值的格式:float 类型

import urllib3

def test_timeout():
    pm = urllib3.PoolManager()
    # 访问这个地址,服务器会在3秒后响应
    url = "http://httpbin.org/delay/3"
    # 设置超时时长
    resp = pm.request(method='GET', url=url, timeout=4.0)
    assert resp.status == 200

HTTPS 请求默认需要校验证书
PoolManager 的 cert_reqs 参数"CERT_REQUIRED":需要校验;“CERT_NONE”:取消校验

import urllib3
import json

def test_HTTPS():
    # 创建不校验证书的连接池对象
    pm_https = urllib3.PoolManager(cert_reqs="CERT_NONE")
    url = "https://httpbin.ceshiren.com/get"
    # 发送HTTPS请求
    resp = pm_https.request(method='GET', url=url)
    print(json.dumps(resp.data.decode('utf-8')))

Python 装饰器

函数引用:函数可以被引用;函数可以被赋值给一个变量。

def school():
    print("school")
harry = school# 把函数对象赋值给一个变量
harry()

闭包函数:闭包的内部函数中,对外部作用域的变量进行引用;闭包无法修改外部函数的局部变量;闭包可以保存当前的运行环境。

def output_student(grade):
    def inner(name, gender):
        print(f"学生的名称是{name},性别是{gender},
        \年级是{grade}")
    return inner

student = output_student(1)
student("罗恩", "男")
student("哈利", "男")
student("赫敏", "女")

为什么要学习装饰器?
行业需求: 涉及 Python 技术栈,面试常见题
使用需求: 优化代码的可读性,可维护性

需求:函数体开始执行与结束执行的时候分别添加打印信息

# 不使用装饰器的代码
def timer(func):
    print("计时开始")
    func()
    print("计时结束")

def school():
    print("school")

timer(hogwarts)
# 使用装饰器的代码
def timer(func):
    def inner():
        print("计时开始")
        func()
        print("计时结束")
    return inner

@timer
def school():
    print("school")

hogwarts()

基本装饰器

def timer(func):
    def inner(*args, **kwargs):
        func(*args, **kwargs)
    return inner

@timer
def aaa(name):
    print(f"aaa:{name}")

aaa("Tom")

练习:实现一个计时器的装饰器,计算函数执行时间

import datetime
def timer(func):
    def inner(*args, **kwargs):
        # 获取当前时间
        start_time = datetime.datetime.now()
        func(*args, **kwargs)
        end_time = datetime.datetime.now()
        print(f"函数的执行时间{end_time-start_time}")
    return inner

@timer
def school(name):
    print("school", name)

你可能感兴趣的:(测试学习笔记,python,开发语言)