Python高级功能

标签: Python 分类: Python 创建时间:2020-06-15 12:51:34 更新时间:2025-04-28 14:37:40

1.发送邮件

发送邮件其实也是简单的,菜鸟教程上,跟着做就好了,没有任何的压力。

2.导入当前目录下的文件

在windos下,如果想要导入当前目录下的文件,需要先使用sys.path.append(‘.’)将当前目录加入到环境变量中,然后再进行导入包的操作,linux就不需要。但是导入上级目录模块,就需要处理了。

1
2
3
4
5
6
7
8
#!/usr/bin/python3
# -*- coding: UTF-8 -*-

import sys
## 导入当前目录包
sys.path.append('.')
## 导入邮件发送
import qqmail

注意:如果一个文件作为一个单独的py文件执行,使用sys.path.append(‘.’)导入当前包是没有问题的,但是如果是作为一个子包引入,就会存在问题,还是找不到相应的包。解决方法就是使用from的引入方法代替import方法,比如下面的代码,从当前目录下的PYSQL.py文件中导入类MSSQL

1
from .PYSQL import MSSQL

有如下的解释:

对于不在sys.path中,一定要避免用import导入 自定义包(package)的子模块(module),而要用from…import… 的绝对导入 或相对导入,且包(package)的相对导入只能用from形式。

【解决方案】

1
2
3
4
5
6
7
8
import os
# 导入当前目录模块
sys.path.append("..")
from . import classes

# 导入运行目录模块
sys.path.append(os.path.dirname(sys.path[0]))
from . import classes
参考文章:
【1】.python import 如何引入当前目录的.py文件?
【2】.Python 3.x可能是史上最详解的【导入(import)】
【3】.python模块以及导入出现ImportError: No module named ‘xxx’问题
【4】.python基础-同级包模块导入、__init__、syspath导入存在的问题、绝对相对导入、单独包导入 (sys.path导入模块错误原因,这里有说明为什么使用sys.path无法导入当前目录下的包,这是因为在使用单独运行的py文件时,可以使用sys.path,但是如果不是单独运行的,那就会出现问题,但是这篇文章写的有点乱)
【5】.Python 3.x可能是史上最详解的【导入(import)】
【6】.python找不到上级目录的模块?详解其中的奥妙 在windows下pycharm环境中运行一个python项目时是正常的,放在Linux下使用python命令运行就出了错误。提示 ModuleNotFoundError: No module named ‘xxx’。pycharm中为什么不存在这个问题,点击菜单栏Run->Edit Configuration,有一个 Working directory 模块配置。

3.软件包

1
2
3
4
5
6
7
8
9
10
11
12
# 方式一,这里生成的txt,但是vscode里面打开乱码
pip freeze > requirements.txt

## 恢复
$ pip install -r requirements.txt

# 方式二
pip install pipreqs
# 生成当前项目的 安装包
pipreqs .
# 安装
pip install -r requirements.txt
参考文章:
【1】.python 项目自动生成requirements.txt文件 方法一:pip freeze > requirements.txt;方法二:pip install pipreqs
【2】.如何指定pip freeze > requirements.txt生成的文件的编码为UTF-8?
【3】.python freeze 和 恢复

4.linux后台运行pyhton

在linux上后台运行某一个程序,可以使用 nohup ,但是随之而来的另外一个问题,那就是如何在某一个虚拟环境中后台运行某一个程序。

或者是我想错了吗?在使用conda切换虚拟环境之后,然后后台运行,自然还是在这个虚拟环境下运行的。

1
2
3
4
5
6
7
8
## 后台运行
nohup python /data/python/server.py > python.log3 2>&1 &

## 查看进程
ps aux|grep python

## 杀死进程
kill -9 [上一步的进程号]
参考文章:
【1】.linux 下后台运行python脚本
【2】.Linux如何在后台一直运行python程序 后台运行python代码命令:nohup python3 main.py &
【3】.Linux下系统自带python和Anaconda切换

5.工程

(1) 通常的 python 项目,都是以单文件的形式执行的,后来要是做一个Ai识别的项目,就需要工程化的思想了。参考目录如下:

1
2
3
4
5
6
7
8
9
10
11
README.rst
LICENSE
setup.py
requirements.txt
sample/__init__.py
sample/core.py
sample/helpers.py
docs/conf.py
docs/index.rst
tests/test_basic.py
tests/test_advanced.py

(2) Python 项目的目录结构因项目而异,但通常会包含以下几个主要目录和文件:

  • README.md:项目文档,包括项目介绍、安装、使用方法等。
  • LICENSE:项目许可证,规定了项目的使用条件。
  • requirements.txt:记录项目所需的依赖包及其版本号,方便其他人快速安装相应的依赖包。
  • setup.py:定义项目的安装方法,可以通过该文件将项目发布到 PyPI 上。
  • src/:存放项目源代码的主目录。
  • tests/:存放项目测试代码的目录,包括单元测试、集成测试、端到端测试等。
  • docs/:存放项目文档的目录,包括 API 文档、用户手册、设计文档等。
  • data/:存放项目中用到的数据文件等资源。
  • scripts/:存放项目相关的脚本文件,例如批处理文件、自动化部署脚本等。

(3) 当谈到 Python Web 项目时

  • app/:存放应用程序的主目录,包含了处理请求、路由、业务逻辑和数据模型等功能模块。该目录中一般会包含多个 Python 模块。
  • config/:存放配置文件的目录,例如数据库配置、日志配置等。
  • static/:存放静态资源,例如 CSS、JavaScript 和图片等文件。
  • templates/:存放 HTML 模板文件的目录,这些模板将在应用程序中动态生成。
  • tests/:存放测试代码的目录,用于测试应用程序的各种功能和接口。
  • venv/:Python 虚拟环境,用于隔离项目依赖,保证项目的稳定性和可移植性。
  • requirements.txt:记录项目所需的依赖包及其版本号,方便其他人快速安装相应的依赖包。
  • README.md:项目文档,包括项目介绍、安装、使用方法等。
参考文章:
【1】.Python 项目工程化开发指南
【2】.Python 项目工程化开发指南 这里好像一个整体的项目说明
【3】.结构化您的工程 真正的模块 ./sample/ or ./sample.py。Setup.py 如果您的模块包在您的根目录下,显然这个文件也应该在根目录下。Requirements File 一个 pip requirements file 应该放在仓库的根目录。它应该指明完整工程的所有依赖包: 测试, 编译和文档生成。任意包含 init.py 文件的目录都被认为是一个Python包。导入一个包里不同 模块的方式和普通的导入模块方式相似,特别的地方是 init.py 文件将集合 所有包范围内的定义。
【4】.Python 项目以及常见的目录结构 其目录结构与一般 Python 项目略有不同。Python Web 项目通常包括以下主要目录和文件
【5】.python项目结构的最佳实践 选择了 FastAPI 实现简单的服务器。
【6】.教程 - 用户指南 本教程将一步步向你展示如何使用 FastAPI 的绝大部分特性。各个章节的内容循序渐进,但是又围绕着单独的主题,所以你可以直接跳转到某个章节以解决你的特定需求

6.日志

使用 python 的日志框架

1
pip install loguru

配置按天分割文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from loguru import logger
logger = logger.opt(colors=True)
# 配置日志记录文件
# 设置日志文件的路径和格式
LOG_FILE = "app.log"
LOG_FORMAT = "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{message}</level>"
logger.remove() # 移除所有默认的日志处理器
logger.add(
LOG_FILE, # 日志文件路径
format=LOG_FORMAT, # 日志格式
rotation="1 day", # 每天旋转日志文件
compression="zip", # 压缩日志文件
retention="7 day" # 保留7天的日志文件
)
logger.add(sys.stdout,level="INFO") # 输出到标准输出
参考文章:
【1】.python日志记录loguru以及如何记录到两个日志文件中
【2】.Delgan /loguru
【3】.Python 日志记录:6大日志记录库的比较 1.logging - 内置的标准日志模块。2.Loguru - 最流行的Python第三方日志框架。3.Structlog。4.Eliot。5.Logbook。6.Picologging。
【4】.loguru设置按天分割日志,保留1天内容 在上面的示例中,我们定义了 [loguru] 和 [loguru.handlers.file] 两个部分。
【5】.【拓展】Loguru:更为优雅、简洁的Python 日志管理模块
【6】.Python loguru 多个模块使用一个logger对象 这篇文章写了多文件共用了一个logger的情况,在使用loguru库之前,我们需要创建一个全局的logger对象,这样不同的模块就可以共享同一个logger对象。可以使用以下代码创建logger对象。
【7】.python loguru 日志级别与按天分割并删除历史日志实践 在 loguru 库中,使用 rotation 参数来按时间间隔分隔日志,同时使用 retention 参数来自动删除旧的日志文件。
【8】.Python 日志模块Loguru基本使用和封装使用 Loguru与logging的区别和优势:简洁性、自动化、灵活性、高效性。封装一个loguru,目录结构:一般都是放在一个utils文件夹下,提供了相关的配置文件。

7.Mino操作

参考文章:
【1】.Python Minio 工具类封装 写了一个 Minio 的工具类。
【2】.MinIO服务器搭建步骤 python 操作MinIO,这里封装之后的接口,和上面的一样:1.查询桶是否存在。2.上传文件,若文件已存在,会直接覆盖。3.获取文件数据写入指定文件。4.直接将文件下载到本地。5.删除文件。6.删除多个文件。

9.配置文件

增加一个 conf 模块,使用的时候就是 conf=conf.getConf()。在一个文件中定义的变量,可以在另外一个文件中访问。

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
import os
import sys
import configparser

# 配置
conf=dict({})

# 读取配置
def load_env():
# 读取并设置全局变量
configPath=os.path.abspath(os.path.join(sys.path[0], ".."))
configFile = configPath+'/conf/config.ini'
# 创建配置文件对象
con = configparser.ConfigParser()
# 读取文件
con.read(configFile, encoding='utf-8')
# 获取所有section
items = con.items('common')
items = dict(items)

global conf
conf=items

def getConf():
return conf

load_env()
参考文章:
【1】.python读取配置文件方式(ini、yaml、xml) 这里代码简单。
【2】.Python读取配置文件
【3】.Python全局变量跨模块变量定义和使用 这里设置了多模块共用一个配置文件
【4】.如何写 python 项目 config 配置 这里分为了测试代码和正式环境代码,可以作为参考
【5】.python获取当前运行程序所在目录 1.获取脚本运行所在目录;2.获取当前运行路径;3.脚本文件路径;
【6】.python 获取当前目录 上一级目录 上上一级目录 os.getcwd() 方法获取路径
【7】.超全!Python中常见的配置文件写法 目前常用且流行的配置文件格式类型主要有 ini、json、toml、yaml、xml 等,这些类型的配置文件我们都可以通过标准库或第三方库来进行解析。

10.defaultdict(lambda: [])

我在运行目标识别的时候,很多的文章都有这么一句话,使用的时候就是让我莫名其妙,明明就是没有 track_history[track_id]=”” 这种赋值,为什么就可以直接使用了呢?

1
2
3
4
5
6
# 声明
track_history = defaultdict(lambda: [])

# 使用
track = track_history[track_id]
track.append((float(x), float(y))) # x, y center point

后来我理解是,这个用法如果 “当字典里的键不存在时新建一个带默认值的键” ,这样就好理解了。突然发现新大陆了,这里也就可以解释为,如果 track_history[track_id] 这个值不存在,就返回一个默认的空数组。

参考文章:
【1】.关于lambda在defaultdict中的用法 为了合并“当字典里的键不存在时新建一个带默认值的键”和“运用新建的键加以计算”这两步存在的
【2】.Python 中的預設字典 字典和 defaultdict 的功能幾乎相同,除了 defaultdict 從不引發 KeyError 之外。它為不存在的鍵提供預設值。
【3】.Python collections.defaultdict()与dict的使用和区别 这里的defaultdict(function_factory)构建的是一个类似dictionary的对象,其中keys的值,自行确定赋值,但是values的类型,是function_factory的类实例,而且具有默认值。比如defaultdict(int)则创建一个类似dictionary对象,里面任何的values都是int的实例,而且就算是一个不存在的key, d[key] 也有一个默认值,这个默认值是int类型值0.
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。