Skip to content

python

fastapi

FastAPI 特点

  • 基于Starlette和Pydantic,利用异步(asynchronous)编程
  • 1、Pythonic:使用Python的自然语法和类型提示,降低学习曲线
    • Pydantic 是一个用于数据验证和序列化的 Python 模型库;from pydantic import BaseModel
    • 使用 Pydantic 定义一个模型只需创建一个继承自 pydantic.BaseModel 的类;
    • 并在其中定义字段,字段的类型可以是任何有效的 Python 类型,也可以是 Pydantic 内置的类型;
    • 使用Pydantic 模型用作请求体(Request Body),以自动验证和解析客户端发送的数据;
    • 返回 Pydantic 模型,路由处理函数返回一个 Pydantic 模型实例,FastAPI 将自动将其转换为 JSON 格式;
    • class Item(BaseModel): name: str description: str = None price: float tax: float = None
  • 2、Starlette框架:利用异步编程实现性能优越。
  • 支持WebSocket

使用流程

  • 1、导入库 from fastapi import FastAPI
  • 2、初始化框架 app = FastAPI()
  • 3、定义装饰器路由+路由对应的方法
    • @app.get("/items/")
    • def read_item(skip: int = 0, limit: int = 10, q: str = None): return {"skip": skip, "limit": limit}
    • @app.post("/items/")
    • def create_item(item: Item): return item
    • item是一个Pydantic 模型,如上特点
  • 启动:uvicorn main:app --reload

请求和响应

  • FastAPI 提供了强大的工具来解析请求数据,并根据需要生成规范的响应。
  • 路由处理函数返回一个字典,该字典将被 FastAPI 自动转换为 JSON 格式,并作为响应发送给客户端;
  • 路由处理函数返回一个 Pydantic 模型实例,FastAPI 将自动将其转换为 JSON 格式,并作为响应发送给客户端:
  • 使用 Header 和 Cookie 类型注解获取请求头和 Cookie 数据。from fastapi import Header, Cookie
  • 使用 HTTPException 抛出异常,返回自定义的状态码和详细信息。
  • raise HTTPException(status_code=404, detail="Item not found")
  • 使用 JSONResponse 自定义响应头:JSONResponse(content=content, headers=headers)

依赖注入系统

  • FastAPI 提供了简单易用,但功能强大的依赖注入系统;
  • 依赖项是在路由操作函数执行前或后运行的可复用的函数或对象,用于执行一些通用的逻辑,如验证、身份验证、数据库连接等:
  • 预处理(Before)依赖项: 在路由操作函数执行前运行,用于预处理输入数据,验证请求等;
  • 后处理(After)依赖项: 在路由操作函数执行后运行,用于执行一些后处理逻辑,如日志记录、清理等;
  • 使用方法(Depends):
    • def read_items(commons: dict = Depends(common_parameters)):
    • common_parameters是一个依赖项函数,用于预处理查询参数;

表单数据

  • 提供了 Form 类型,可以用于声明和验证表单数据;
  • 要使用表单,需预先安装:pip install python-multipart;
  • from fastapi import FastAPI, Form
  • 这样就是一个接收表单的数据了
  • def login(username: str = Form(), password: str = Form()):
  • 在Pydantic模型中声明表单数据模型,使用 Field 类型声明每个表单字段,并添加必要的验证规则。
  • desc: str = Field(None, title="Item Description", max_length=255)
  • 在路由操作函数中,可以使用 Form 类型来接收表单数据。
  • 处理文件上传
    • from fastapi import FastAPI, File, UploadFile
    • async def create_file(file: UploadFile = File(...)):
    • FastAPI 将负责处理文件上传,并将文件的相关信息包装在 UploadFile 对象中,可以轻松地获取文件名、内容类型等信息。

flask

  • Flask 是什么

    • Flask 本身只依赖两个库( Werkzeug/worktool 和 Jinja2 )
      • Werkzeug:有路由系统,也出色地实现了 WSGI 协议,包括多部分表单数据解析、HTTP日期处理、缓存控制头等;
      • Jinja2: 是模板引擎,处理模板的;
    • Flask 也绑定了一些通用的标准库包,比如logging,除此 之外其它所有一切都交给扩展来实现。
  • 使用流程

    • 和fastApi的3个步骤一样,只是启动用flask run,启动需要设置一些环境变量
      • FLASK_APP
      • FLASK_ENV=development
      • FLASK_RUN_PORT=5000
    • 有click、celery库的集成,SQLAlchemy有单独的适配包;
    • 用pip install virtualenv来引入.env文件
  • 使用Setuptools部署项目

    • 写一个setup.py描述项目及其从属的文件。from setuptools import find_packages, setup
    • 还需要一个名为 MANIFEST.in 文件来说明这些文件有哪些。
    • 这个命令告诉 pip 在当前文件夹中寻找 setup.py 并在 编辑 或 开发 模式下安装,pip install -e .
    • 然后就可以通过 pip list 来查看项目,也可以在任何地方运行应用了;

Django

  • django框架是什么

    • 是一个由Python编写的具有完整架站能力的开源Web框架。使用Django,只要很少的代码。
    • 功能完善、要素齐全:该有的、可以没有的都有,自带大量常用工具和框架,无须你自定义、组合、增删及修改。
    • 强大的数据库访问组件:Django的Model层自带数据库ORM组件,无须学习其他数据库访问技术(SQL、pymysql、SQLALchemy等)。
    • 灵活的URL映射:Django使用正则表达式管理URL映射,灵活性高。
    • 丰富的Template模板语言:类似jinjia模板语言,不但原生功能丰富,还可以自定义模板标签,并且与其ORM的用法非常相似。
    • 框架庞大,被认为不够精简、捆绑的内容太多。在异步通信方面略有欠缺;
    • flask的框架,虽然精简,但是你要自己安装各种工具、ORM、插件等等;
    • Django对传统的MVC设计模式进行了修改,将视图分成View模块和Template模块两部分,MVT=MVC
      • 模型(Model):和MVC中的定义一样
      • 模板(Template):将数据与HTML语言结合起来的引擎
      • 视图(View):负责实际的业务逻辑实现,这个就是控制器controller
  • 使用流程

    • pip install django # django==2.2 指定版本安装
    • 1、创建一个项目 django-admin startproject mysite # 项目是管理中心,天然适合多应用开发的模式,1个项目->N个应用
    • 2、创建一个应用 python manage.py startapp myapp
    • 3、添加模型 python manage.py makemigrations blog
    • 4、模型生成sql入库 python manage.py migrate
    • 5、安装应用settings.py、添加路由、引入路由
    • 启动项目 python manage.py runserver
    • 创建超级用户用于管理后台 python manage.py createsuperuser
  • 有的功能

    • orm和migrate
    • 中间件(middleware)
    • 信号(event)
    • admin

面向对象

  • class 的第一个参数self代表类的实例,代表当前对象的地址,而非类,而 self.class 则指向类;

  • 类的方法与普通的函数只有一个特别的区别,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例;

  • 类属性与方法

    • 私有属性:两个下划线开头,声明该属性为私有,在类内部的方法中使用时 self.__private_attrs。
    • 私有方法:两个下划线开头,声明该方法为私有方法,self.__private_methods。
    • 运算符重载:可以对类的专有方法进行重载,对类的专有方法进行重写
      • 类的专有方法: init : 构造函数,在生成对象时调用 del : 析构函数,释放对象时使用 repr : 打印,转换 setitem : 按照索引赋值 getitem: 按照索引获取值 len: 获得长度 cmp: 比较运算 call: 函数调用 add: 加运算 sub: 减运算 mul: 乘运算 truediv: 除运算 mod: 求余运算
  • 继承

    • 子类(派生类 DerivedClassName)会继承父类(基类 BaseClassName)的属性和方法。
    • class DerivedClassName(modname.BaseClassName):
    • Python同样有限的支持多继承形式。class DerivedClassName(Base1, Base2, Base3):
    • super() 函数是用于调用父类(超类)的一个方法。super(Child,c).myMethod() #用子类对象调用父类已被覆盖的方法
    • super() 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序等种种问题。
  • 方法重写(多态)

    • 如果父类方法的功能不能满足需求,就可以在子类重写父类的方法;
    • 直接定义和父类一样的方法名称就可以;
  • 命名空间和作用域

    • Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域;
      • 其它的代码块(如 if/elif/else/、try/except、for/while等)
      • 不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问
    • 一般有三种命名空间:
      • 内置名称(built-in names), Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等。
      • 全局名称(global names),模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。
      • 局部名称(local names),函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)
    • 命名空间查找顺序为:局部的命名空间 -> 全局命名空间 -> 内置命名空间。
    • 作用域
      • 作用域就是一个 Python 程序可以直接访问命名空间的正文区域。
      • 在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
      • Python 的作用域一共有4种
        • 规则顺序: L –> E –> G –> B。
        • L(Local):最内层,包含局部变量,比如一个函数/方法内部。
        • E(Enclosing):
          • 包含了非局部(non-local)也非全局(non-global)的变量。
          • 比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
        • G(Global):当前脚本的最外层,比如当前模块的全局变量。
        • B(Built-in): 包含了内建的变量/关键字等,最后被搜索。
      • 内置作用域是通过一个名为 builtin 的标准模块来实现的,
      • 可以使用以下的代码来查看到底预定义了哪些变量: import builtins dir(builtins)
    • global 和 nonlocal关键字
      • 当内部作用域想修改外部作用域的变量时,就要用到 global 和 nonlocal 关键字了。
      • global num # 需要使用 global 关键字声明
      • 如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了,如下实例:
      • nonlocal num # nonlocal关键字声明

错误和异常

  • Python 有两种错误:语法错误和异常(运行期检测到的错误被称为异常);
  • 异常以不同的类型出现,类型有 ZeroDivisionError,NameError 和 TypeError。
  • 异常捕捉
    • 可以使用 try/except 语句,一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常;
    • 一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:
    • except (RuntimeError, TypeError, NameError):
    • 最后一个except子句可以忽略异常的名称,它将被当作通配符使用;
    • try/except 语句还有一个可选的 else 子句,如果使用这个子句,那么必须放在所有的 except 子句之后。
    • else 子句将在 try 子句没有发生任何异常的时候执行。
    • try-finally 语句:无论是否发生异常都将执行最后的代码。
  • 抛出异常:
    • Python 使用 raise 语句抛出一个指定的异常,raise [Exception [, args [, traceback]]];
    • raise 唯一的一个参数指定了要被抛出的异常,它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类);
  • 用户自定义异常
    • 你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承,例如:
    • 当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类
    • 大多数的异常的名字都以"Error"结尾,就跟标准的异常命名一样。

标准库

  • Python 标准库非常庞大,所提供的组件涉及范围十分广泛,以下是一些 Python3 标准库中的模块:
  • os 模块:os 模块提供了许多与操作系统交互的函数,例如创建、移动和删除文件和目录,以及访问环境变量等。
  • sys 模块:sys 模块提供了与 Python 解释器和系统相关的功能,例如解释器的版本和路径,以及与 stdin、stdout 和 stderr 相关的信息。
  • time 模块:time 模块提供了处理时间的函数,例如获取当前时间、格式化日期和时间、计时等。
  • datetime 模块:datetime 模块提供了更高级的日期和时间处理函数,例如处理时区、计算时间差、计算日期差等。
  • random 模块:random 模块提供了生成随机数的函数,例如生成随机整数、浮点数、序列等。
  • math 模块:math 模块提供了数学函数,例如三角函数、对数函数、指数函数、常数等。
  • re 模块:re 模块提供了正则表达式处理函数,可以用于文本搜索、替换、分割等。
  • json 模块:json 模块提供了 JSON 编码和解码函数,可以将 Python 对象转换为 JSON 格式,并从 JSON 格式中解析出 Python 对象。
  • urllib 模块:urllib 模块提供了访问网页和处理 URL 的功能,包括下载文件、发送 POST 请求、处理 cookies 等。

数据结构

  • list
    • 常用方法
      • list.append(x)把一个元素添加到列表的结尾,相当于 a[len(a):] = [x]。
      • list.extend(L)通过添加指定列表的所有元素来扩充列表,相当于 a[len(a):] = L。
      • list.insert(i, x)在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x)会插入到整个列表之前,
      • list.remove(x)删除列表中值为 x 的第一个元素。如果没有这样的元素,就会返回一个错误。
      • list.pop([i])从列表的指定位置移除元素,并将其返回。如果没有指定索引,a.pop()返回最后一个元素。元素随即从列表中被移除。
      • list.clear()移除列表中的所有项,等于del a[:]。
      • list.index(x)返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。
      • list.count(x)返回 x 在列表中出现的次数。
      • list.sort()对列表中的元素进行排序。
      • list.reverse()倒排列表中的元素。
      • list.copy()返回列表的浅复制,等于a[:]
    • 将列表list当做堆栈使用
      • 列表方法使得列表可以很方便的作为一个堆栈来使用
      • 用 append() 方法可以把一个元素添加到堆栈顶;
      • 用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来;
    • 将列表list当作队列使用
      • queue.append("Terry")
      • queue.popleft()移除最左边的元素,也就是出队。
    • del 语句可以从一个列表中根据索引来删除一个元素,而不是值来删除元素
      • 这与使用pop()返回一个值不同。可以用 del 语句从列表中删除一个切割
      • del a[2:4]
      • del a[0]
    • 列表推导式
      • 列表推导式提供了从序列创建列表的简单途径。
        • 通常应用程序将一些操作应用于某个序列的每个元素,用其获得的结果作为生成新列表的元素,或者根据确定的判定条件创建子序列。
  • 集合
    • 集合是一个无序不重复元素的集。基本功能是消除重复元素。
    • 可以用大括号(\{\})创建集合。注意,如果要创建一个空集合,你必须用 set() 而不是 \{\} ,后者创建一个空的字典
    • basket = \{'apple', 'orange', 'apple', 'pear', 'orange', 'banana'\}
    • 会自动删除重复的元素
    • orange' in basket # 检测成员,返回true or false
    • 可以求交集、差集、并集 a - b、a | b、a & b 、a ^ b
  • 字典
    • 字典以关键字为索引,关键字可以是任意不可变类型,通常用字符串或数值。
    • 一对大括号创建一个空的字典:{}。
    • 构造函数 dict() 直接从键值对元组列表中构建字典
    • 在字典中遍历时,关键字和对应的值可以使用 items() 方法同时解读出来:
    • for k, v in knights.items():
  • 推导式
    • 推导式是一种独特的数据处理方式,可以从一个数据序列构建另一个新的数据序列的结构体,Python 支持各种数据结构的推导式:
      • 列表(list)推导式
      • 字典(dict)推导式
      • 集合(set)推导式
      • 元组(tuple)推导式
    • 以上四种数据结构,推导式格式都有两种:
      • [表达式 for 变量 in 列表]
      • names = ['Bob','Tom','alice','Jerry','Wendy','Smith']
      • new_names = [name.upper() for name in names if len(name)>3]
      • [表达式 for 变量 in 列表 if 条件]

各项基础

  • 三目运算符
    • Python中没有三目运算符: ?:,但是有
    • [on true] if [expression] else [on false] 如果表达式为True,就执行[on true]中的语句。否则,就执行[on false]中的语句。
    • a, b = 2, 3
    • min = a if a < b else b
  • "*args"和kwargs的含义
    • 当我们不知道向函数传递多少参数时,比如我们向传递一个列表或元组,我们就使用args,def func(*args)
    • 在我们不知道该传递多少关键字参数时,使用 **kwargs 来收集关键字参数
    • def func(**kwargs):
  • random模块的shuffle()函数,可以就地操作方式打乱一个列表的元素
  • join()和split()函数
    • Join()能将指定字符添加至字符串中,','.join('12345') # out 1,2,3,4,5
    • Split()能让我们用指定字符分割字符串,print('1,2,3,4,5'.split(',')),out ['1', '2', '3', '4', '5']
  • Python 是区分大小写的
  • 字符串函数
    • print(' Ayushi'.lstrip())
    • print('Ayushi '.rstrip())
    • print('AyuShi'.lower())
    • print('AyuShi'.upper())
    • print('AyuShi'.isupper())
    • 'The Corpse Bride'.istitle()
  • pass语句:可以用pass定义空函数
  • Python中的闭包:嵌套函数就是一个闭包,例如A函数返回一个函数,A(7)()
  • Python中的//,** 运算符
    • // 运算符执行地板除法(向下取整除),它会返回整除结果的整数部分。
    • 执行取幂运算,print(2**10) out 1024
  • Python中有3个逻辑运算符:and,or,not
    • print(False and True)
    • print(7 < 7 or True)
    • print(not 2==2)
  • 成员运算符’in’和’not in’,我们可以确认一个值是否是另一个值的成员
    • print('me' in 'disappointment') # out True
    • print('us' not in 'disappointment') # out True
  • 身份运算符’is’和’is not’,我们可以确认两个值是否相同
    • print(10 is '10') # out False
    • print(True is not False) # out True
  • Python并没有私有变量的概念,所以约定速成以下划线为开头来声明一个变量为私有;
  • WSGI:
    • (Web Server Gateway Interface,Web服务器网关接口)是一种接口标准;
    • 它定义了Web服务器和Web应用程序之间的一致性接口,从而实现Web应用程序的自我维护;
    • 就好比一个胶带,它把Web服务器和Web应用程序牢牢连接在一起,
  • python项目上线部署
    • Web应用程序,需要配置一个Web服务器(如Nginx或Apache)来处理HTTP请求,并将请求转发给Python应用程序。
    • 通常会使用WSGI(Web服务器网关接口)来与Python应用程序进行通信。
  • WSGI和FastCGI的区别一下哪些
    • FastCGI是语言无关的、可伸缩架构的CGI开放扩展,
      • 其主要行为是将CGI解释器进程保持在内存中并因此获得较高的性能。
      • PHP-FPM 会启动多个 PHP 解释器进程,并监听一个特定的端口,等待 Web 服务器的连接请求;
      • PHP-FPM是作为FastCGI 进程的管理者,负责处理PHP解释器进程与 Web 服务器(如 Nginx 或 Apache)之间的通信。
      • CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量;
    • WSGI是Python的一种规范,是Web服务器与应用程序或应用框架之间的一种低级别的接口;
  • 协程
    • 在Python中,async和await是协程(coroutine)的关键字,结合asyncio模块使用(在python3.5中引入)
    • await表达式只能在async def函数内部使用。
    • 许多 asyncio API 都被设计为接受可等待对象。可等待 对象有三种主要类型: Coroutine(协程),task(任务) 和 Future;
    • run create_task gather/TaskGroup 常用,都在asyncio.下使用,这些写在async函数里面,再调用运行asyncio.run(proxyMainV3())

ORM框架

  • 四种常用ORM

    • Django ORM:是Django Web框架的一部分
    • SQLAlchemy是Python中最受欢迎的ORM框架之一
      • 它提供了两个API层次,即“Core”和“ORM”。
      • Core层提供了非常基本的数据库操作,包括执行原始SQL查询和处理结果;
      • 而ORM层提供了高级的面向对象操作,包括映射数据库表到Python类,执行复杂的查询和关系映射等功能。
    • Peewee:它的设计目标是简单性和易用性,能够自动生成数据表定义;
    • sqlmodel:Python 数据库管理ORM 的终极形态
  • 使用ORM的好处:更加易于使用、更加灵活、能防止 SQL 注入攻击、更加易于测试的优势。

  • sqlmodel和SQLAlchemy的比较:

    • 如果需要使用全面的ORM功能,或者需要使用复杂的查询构建和事务处理等功能,建议选择SQLAlchemy。
    • 如果需要使用轻量级的ORM功能,或者需要快速上手和使用,建议选择sqlmodel。
    • 如果需要支持多种数据库,建议两者都可以考虑使用。
    • 如果对文档和社区支持有较高的要求,建议选择SQLAlchemy。
    • 如果对代码规范有较高的要求,建议选择sqlmodel。
  • SQLModel

    • SQLModel 基于Python类型注释,并由Pydantic和SQLAlchemy提供支持;
    • Pydantic、SQLAlchemy的model和SQLModel是通用的,在fastAPI中写一个model就可以进行参数验证和数据库写入;
    • SQLModel用继承基础基础model这一点比SQLAlchemy需要写多处同一个model,这个就比较方便;
    • db = Session(engine)手动close,或者用with只是自动关闭连接;
    • curd和多表操作都有对应的方法实现,也可以使用session对象执行原生SQL查询。都没有laravel的orm一半好用;
    • https://www.cnblogs.com/Detector/p/17458890.html

工具

  • drissionPage
  • Selenium
  • Playwright
  • scrapy
    • pip install scrapy
    • 创建一个爬虫并启动的过程
      • scrapy startproject scrapyDemo # 创建一个项目
      • scrapy genspider itcast "baidu.com" # 创建一个爬虫
      • scrapy runspider spiders/demo.py # 运行爬虫
      • scrapy crawl itcast # 2.7 or 3.0之前的版本才有crawl命令
    • 包含的功能
      • pipeline:类似于调度爬虫的调度器,爬取、接收一个response对象,处理后返回item对象或requests对象;
      • spider:
        • 爬虫类,用于定义爬取的逻辑,包括如何解析response对象,如何提取item对象,如何生成requests对象
        • spider目录下包含的genspider命令运行后创建爬虫文件;
        • 每个爬虫都有一个parse方法用于接收response对象,返回item对象或requests对象
      • item:xpath解析的数据存入模型
      • middleware
      • settings
  • mediaCrawler
    • mediaCrawler的启动过程
      • 1、main.py是入口,通过配置来实例化对应的平台类,多个平台都实现同样的抽象类;
      • 2、获取数据后存到数据库 or 文件(json/csv),通过配置来实例化对应的存储类,这三个类都实现同样的抽象类;
      • 3、playwright登陆网页版的各个平台,我操作了小红书的完整例子,还看了源码;
      • 4、写了abc、async-await的例子
      • 5、opencv-python用来识别验证码
    • playwright无头浏览器
      • playwright screenshot learnku.com bai.png --full-page
    • 运行爬虫
      • python main.py --platform xhs --lt qrcode --type creator
      • python main.py --platform xhs --lt qrcode --type detail

和PHP的区别

  • 面向对象:单继承和PY是多继承的,类方法的第一个参数是self;
  • 与web服务器通信的接口不同:WSGI和FastCGI;
  • 语言特性
    • 推导式:四种数据结构都有“推导式”的方式构造新数据组合;
    • 运算符:
      • 没有三目运算符: ?:,但是有on true if else替代;
      • and,or,not,’in’和’not in’
    • python语言层面支持协程异步IO、装饰器;