python相关教程

一、相关介绍

1. python装饰器

传说中Python最难理解的点|看这完篇就够了

1.1 相关介绍

函数也是对象,可以作为对象赋值给另外一个变量;

函数可以嵌套,定义在另外一个函数内部;

函数作为参数返回,一个函数可以当做另外一个函数的返回值;

函数作为参数传入,一个函数可以当作另外一个函数的参数传入;

1.2 装饰器

装饰器是对一个函数在运行期的功能的拓展,装饰器有一个语法糖@。

@my_new_decorator其实相当于
another_stand_alone_function=my_new_decorator(another_stand_alone_function)

1.3 @functools.wraps(func)

功能:还原被装饰的函数名

问题引入

装饰器加上之后,解释器认为函数本身发生了改变,其函数本身的属性改变了,在某些情况下,比如测试时,会导致一些问题。

相关介绍

当装饰器装饰一个函数时,实际上就是将被装饰的函数作为一个参数传入装饰器函数,返回一个闭包,而闭包内部调用这个函数。被装饰的函数的 __name__ 等属性其实已经改变,变成了闭包的私有属性。

functools.wraps()这个函数将被装饰的函数的属性还原为原属性。

注意:反正记住写装饰器的时候,最好是加上@functools.wraps(func),这样可以在扩展函数功能的同时,保证装饰器不会对被装饰函数造成影响,保留原有函数的各种属性

@deco1
@deco2
def foo():
    print('foo')

执行 foo()
deco1和deco2是两个装饰器,相当于deco1(deco2(foo))

2. IPython && Jupyter

ipython是使用python构建的交互式shell,Jupyter是其web化的包装。

3. pyc文件

pyc文件是python编译后的字节码,也可以由python解释器执行。

4. wheel文件和egg文件

wheel文件和egg文件都是项目版本发布的打包文件,wheel是最新标准。

5. 编程语言自举

Go语言在1.5版本实现自举。Go语言在1.5版本之前使用c实现的编译器,在1.5版本时候使用Go实现了自己的编译器,这里有一个鸡生蛋和蛋生鸡的过程,也挺有意思。

pypy使用python的子集rpython实现了解释器,和Go语言的自举有点类似。反常识的是rpython的解释器会比c实现的解释器快?主要是因为pypy使用了JIT技术。

6. site-packages与dist-packages

  • 系统自带软件管理器安装路径: dist-packages /usr/lib/python2.7/dist-packages/
  • ROS安装路径:/opt/ros/kinetic/lib/python2.7/dist-packages
  • pip默认安装路径:/usr/local/lib/python2.7/dist-packages/
  • 非root用户安装路径:~/.local/lib/python2.7/site-packages

二、常用操作汇总

1. 文件操作

1.1 文件命名

# 绝对路径
path_name = '/home/yoyo/MyDocuments/PyProjects/monodepth-master/image.png'

# 文件夹路径
dir_name = '/home/yoyo/MyDocuments/PyProjects/monodepth-master'

# 文件名
file_name = 'image.png'
base_name = 'image.png'

# 前缀
prefix_name = 'image'

# 后缀
postfix_name = '.png'

base_name = os.path.basename(path_name)
prefix_name = os.path.splitext(base_name)[0]
postfix_name = os.path.splitext(base_name)[1]
dir_name = os.path.dirname(path_name)

1.2 创建文件夹

# 创建指定的目录,如果上一级目录不存在,则无法创建成功
os.mkdir()

# 递归创建目录
os.makedirs()

1.3 删除文件夹

import shutil


# 删除整个文件夹,如果为空也删除
shutil.rmtree(目录路径)

1.4 拷贝文件夹

Windows命令行复制文件夹

  1. 无论文件夹是否为空,均可以复制,而且会复制文件夹中的所有内容;
  2. 如果dst目录存在,则拷贝失败;
import shutil

# dst目录不存在,直接拷贝
shutil.copytree(src目录, dst目录)

# dst目录为空,删除dst目录后,再拷贝到dst目录
shutil.rmtree(dst目录)
shutil.copytree(src目录, dst目录)

# dst目录不为空
# windows 平台
import subprocess
subprocess.run("xcopy {}/E/F/K {}".format(src_path, dst_path), shell=True, encoding="utf-8")

# Linux 平台
import subprocess
subprocess.run("cp -r {} {}".format(src_path, dst_path), shell=True, , encoding="utf-8")

1.5 常用API

# 获取当前文件的绝对路径
path_name = os.path.abspath(__file__)

# 获取当前文件所在的根目录
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

2. 数据类型相关

2.1 字典的update()方法

Python字典的update()方法,常用于深度学习PyTorch中模型参数加载和模型迁移
总结: d1.update(d2)的作用是,将字典d2的内容合并到d1中,其中d2中的键值对但d1中没有的键值对会增加到d1中去,两者都有的键值对更新为d2的键值对.

Python 3.7.4 (tags/v3.7.4:e09359112e, Jul  8 2019, 20:34:20) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>> d1 = {"浙江":"杭州","江苏":"nanjing"}
>>> d1
{'浙江': '杭州', '江苏': 'nanjing'}
>>> d1.update(江苏="南京")
>>> d1
{'浙江': '杭州', '江苏': '南京'}
>>> d2 = {"山东":"济南","河北":"石家庄"}
>>> d1
{'浙江': '杭州', '江苏': '南京'}
>>> d1.update(d2)
>>> d1
{'浙江': '杭州', '江苏': '南京', '山东': '济南', '河北': '石家庄'}
>>> d3 = {"浙江":"杭州市*****"}
>>> d1
{'浙江': '杭州', '江苏': '南京', '山东': '济南', '河北': '石家庄'}
>>> d1.update(d3)
>>> d1
{'浙江': '杭州市*****', '江苏': '南京', '山东': '济南', '河北': '石家庄'}
>>> 
>>> 

2.2 str转dict

import ast


def parse_str_2_dict(str_data:str):
    """
    解析指令,字符串转换成字典
    :param str_data: "{'key': value, 'key': value}"
    :return: {'key': value, 'key': value}
    """
    try:
        return ast.literal_eval(str_data) ## 如果解析成功
    except:
        return None ## 如果解析失败

2.3 str转list

# "[1, 3, 16, 112, 112]" ---> [1, 3, 16, 112, 112]

str_data = "[1, 3, 16, 112, 112]"
list_data = [int(_) for _ in str_data.strip("[").strip("]").split(",")]

2.4 list转str

input_shape = [1, 2, 3, 4, 5]
str_num = [str(i) for i in input_shape]  # ['1', '2', '3', '4', '5']
input_shape = ','.join(str_num)  # '1,2,3,4,5'
input_shape = "["+input_shape+"]"  # '[1,2,3,4,5]'

三、常用模块

1 Pillow库

PIL,Python Imaging Library,是Python平台上的图像处理标准库。PIL功能强大,API简单易用。

由于PIL仅支持到Python 2.7,加上年久失修,于是一群志愿者在PIL的基础上创建了兼容的版本,名字叫 Pillow,支持最新Python 3.x,又加入了许多新特性,因此,我们可以直接安装使用Pillow。

安装Pillow

pip install pillow

2. tempfile模块

import tempfile

tmpdir = tempfile.mkdtemp()  # 创建临时文件夹

3. struct 模块

原理 : 将一组简单数据进行打包,转换为bytes格式发送,或者将一组bytes个数数据转换为python数据类型

【1】st = Struct(fmt)
功能: 生成结构化对象
参数: fmt 定制的数据结构

【2】 st.pack(v1,…)
功能: 将一组数据按照指定格式打包转换
参数: 要打包的数据
返回值: bytes字节串

【3】 st.unpack(bytes_data)
功能: 将bytes字节串按照格式解析
参数: bytes字节串
返回值: 解析后的数据元组

4. pytest模块

(十八)–doctest测试框架

Python测试框架-doctest几种简单应用方式

4.1 pytest运行

pytest框架可以兼容doctest用例,执行的时候加个参数 --doctest-modules,这样它就能自动搜索到doctest的用例。

pytest -v --doctest-modules demo.py

demo.py

def by(m,n):
    """
    function:两个数相乘
    >>> by(4,3)
    12
    >>> by('ab',3)
    'ababab'
    """
    return m*n


if __name__=="__main__":
    import doctest
    doctest.testmod(verbose=True)

4.2 pytest独立文件

python -m doctest -v demo.txt

demo.py

def by(m,n):
    """
    function:两个数相乘
    >>> by(4,3)
    12
    >>> by('ab',3)
    'ababab'
    """
    return m*n


if __name__=="__main__":
    import doctest
    doctest.testmod(verbose=True)  

demo.txt

>>> from demo import by
>>> by(4,3)
12
>>> by('ab',3)
'ababab'

5. doctest模块

Python测试框架doctest

doctest是python自带的一个模块,你可以把它叫做**“文档测试”(doctest)模块**。doctest模块会搜索那些看起来像是python交互式会话中的代码片段,然后尝试执行并验证结果。

doctest的编写过程就像你在一个交互式shell中导入了一个被测试模块,然后一条一条执行被测试模块里面的函数一样。其实实际上doctest也是这么编写的,写好一个模块之后,在shell中测试这个模块里面的函数,将shell会话中的内容复制粘贴成doctest用例。

'''
这个例子展示如何在源码中嵌入doctest用例。
'>>>' 开头的行就是doctest测试用例。
不带 '>>>' 的行就是测试用例的输出。
如果实际运行的结果与期望的结果不一致,就标记为测试失败。
'''
def multiply(a, b):
    """
    >>> multiply(4, 3)
    12
    >>> multiply('a', 3)
    'aaa'
    """
    return a * b
if __name__=='__main__':
    import doctest
    doctest.testmod(verbose=True)

6. retrying模块

python retrying模块的使用方法详解

问题引入
我们在写爬虫的过程中,经常遇到爬取失败的情况,这个时候我们一般会通过try块去进行重试,但是每次都写那么一堆try块,真的是太麻烦,retrying模块就能很方便的解决这个问题。

retring模块通过装饰器的形式来进行重试操作,举个简单的例子。

from retrying import retry
@retry(stop_max_attempt_number=5,wait_random_min=1000,wait_random_max=5000)
def run():
  print("开始重试")
  raise NameError

if __name__ == '__main__':
  run()

参数解释

  • stop_max_attempt_number:最大重试次数,超过这个次数会停止重试,并报异常。
  • wait_random_min:随机等待最小时间。
  • wait_random_max:随机等待最大时间。

7. 进度条工具

7.1 tqdm模块

在这里插入图片描述

7.2 rich模块

Rich is a Python library for rich text and beautiful formatting in the terminal.

rich的progress模块提供了类比tqdm的进度条展示方法且更加强大。

pip install rich

在这里插入图片描述

8.hashlib模块

【Python】计算文件的MD5、SHA1、SHA256值(校验文件完整性)

8.1 问题引入

某文件在A机器上正常运行,通过一些手段(cp命令,scp命令,U盘等)改变了位置,竟然无法运行了。从文件传输角度考虑,可能是由于部分文件漏传导致的,为此需要校验文件的完整性

8.2 hashlib模块

Python 的内置模块 hashlib 实现文件MD5、SHA1、SHA256值的计算。

import hashlib
# pip install rich
import rich.progress


def encrypt(fpath: str, algorithm: str) -> str:
    with rich.progress.open(fpath, 'rb') as f:
        hash = hashlib.new(algorithm)
        for chunk in iter(lambda: f.read(2**20), b''):
            hash.update(chunk)
        return hash.hexdigest()


if __name__ == '__main__':
    for algorithm in ('md5', 'sha1', 'sha256'):
        hexdigest = encrypt('ubuntu-22.04-desktop-amd64.iso', algorithm)
        print(f'{algorithm}: {hexdigest}')

9. pybind11

pybind11的应用

9.1 适用场景

如果想python调用c++代码,可以使用pybind模块。

C++的速度会比python更有优势,如果想在Python中实现对某些C++的库的调用,可以使用pybind模块,例如:pybind实现了对矩阵处理库eigen的支持。

9.2 简单示例

9.2.1 安装依赖包
sudo apt-get install python3-dev
9.2.2 下载pybind源码
git clone https://github.com/pybind/pybind11.git
9.2.3 项目结构
.
├── build
├── CMakeLists.txt         
├── pybind11      
└── test.cpp
9.2.4 CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(c_matrix C CXX)
set(CMAKE_BUILD_TYPE "Release")
add_subdirectory(pybind11)
pybind11_add_module(test test.cpp)

参数解释

pybind11_add_module() 是Pybind的函数,与cmake的add_library()函数类似,第一个参数表示编译生成的目标文件,例如:test.cpython-36m-x86_64-linux-gnu.so,test即为该参数。

注意:这里的test正是.so名称的第一个 . 之前的名称,也跟 CMakeLists.txt 文件中 pybind11_add_module()第一个参数相同,还跟 test.cpp 中的 PYBIND11_MODULE()第一个参数相同

test.cpp

PYBIND11_MODULE() 是宏的调用代码,是模块的入口函数,是必不可少的一部分。其中,m.doc(),定义了该模块的说明,m.def() 定义了在python中调用的名称,接口名,以及接口的文字说明。

#include <pybind11/pybind11.h>
int add(int i, int j)
{    
    return i + j;
}
 
PYBIND11_MODULE(test, m)
{    
    m.doc() = "pybind11 example plugin"; // optional module docstring    
    m.def("add", &add, "A function that adds two numbers");
}
9.2.5 编译
mkdir build
cd build

cmake ..
make -j 4
9.2.6 测试是否成功

在该.so所在路径下,执行python指令:

>>> import test 
>>> test.add(1, 2)
yoyo@yoyo:/test/build$ python3
Python 3.10.6 (main, Nov  2 2022, 18:53:38) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> test.add(1, 2)
3

10. numba模块

如何用numba加速python?

四、重要知识点

1. tcp套接字数据传输

  1. tcp连接中当一端退出,另一端如果阻塞在recv,则recv会立即返回一个空字串。

  2. tcp连接中如果另一端已经不存在,再试图使用send向其发送内容时会出现BrokenPipeError

  3. 网络收发缓冲区
    【1】缓冲区有效的协调了消息的收发速度;
    【2】send,recv实际是向缓冲区发送接收消息,当缓冲区不为空的时候recv就不会阻塞;

  4. 粘包问题
    【1】原因:tcp以字节流方式传输数据,没有消息边界,多次发送的内容如果被一次接收就会形成粘包。

    【2】影响:如果每次发送的内容是需要独立解析的含义,此时粘包会对消息的解析产生影响。

    【3】处理:(1)人为添加消息边界;(2)控制发送速度。

五、常用操作

1. 查询API

python -m pydoc -p 4567

2. 命令行运行python

python -m doctest -v demo.py

参数解释

  • -m参数指定运行方式doctest;
  • -v参数是verbose,带上-v参数相当于verbose=True,表示将测试成功或失败的信息全部输出,如果设置为False则只在测试失败的时候输出测试信息,该参数默认为False。

3. 导包

3.1 参考资料

[转]Python 相对导入与绝对导入

python导包从入门到精通

3.2 相关介绍

在 python 中,每一个 py 文件都称为模块,每一个具有 init.py 文件的目录称为包。

3.3 有 init.py 文件

说明该文件夹是一个包。

from 包名 import 模块(py)
from 包名 import 模块.函数
from 包名 import 模块.

3.4 没有 init.py 文件

from 模块 import 函数
from 模块 import

3.5 导入不同目录下的函数

import sys
sys.path.append(r'/home/yoyo/MyDocument/Python_Test_Project/20200116')

import upload_file # 调用自定义包 upload_file.py
upload_file.upload_file_result() # 调用函数

3.6 导入不同目录下的类

import sys
sys.path.append(r'/root/MyDocuments/Python_Test_Project/2020_06/20200629/class_demo_v1.py')
from class_demo_v1 import Student
student = Student()

3.8 导入相同目录下的模块

在admin.py文件中要引入相同目录下的dealcode.py模块。

from . import dealcode

3.9 导入相同目录下的类

引入同一目录下的dealcode.py文件中的一个类Hello。

from .dealcode import Hello

4. json格式化输出

python 打印json格式的数据中文显示问题

Python进行JSON格式化输出,以及汉字显示问题

dict_data = {"a": "你好", "b": "zai", "c": "zhe", "d": "li"}
print(type(dict_data))
print(json.dumps(dict_data, sort_keys=True, indent=4, separators=(',', ':'), ensure_ascii=False))

解释说明

ensure_ascii=false,表示不使用ASCII编码,可以显示中文

通过json库里面的dumps方法可以让其显示为中文,默认是以ASCII来解析code,中文不在ASCII编码当中,所以无法正常显示。json.dumps方法讲ASCII编码设置为false即可解决此问题

5. python中执行shell指令

Python - 调用终端执行命令

6. py打包exe可执行文件

python利用pyinstaller打包简明教程

能够from xxx import yyy就尽量不要import xxx,这样可以减少打包后的体积。

pyinstaller打包的exe体积往往都非常巨大,而且打包过程非常耗时,和C/C++编译的exe目测差了几个数量级,所以一般没有这个必要去把一个大的python工程打包成exe可执行文件。我想这也是未来python如果想要成为大型软件开发工程的热门语言所要克服的一个重大缺点吧。

# 安装pyinstaller
pip install pyinstaller

# 打包,打包成功后在dist文件夹下生成exe文件
pyinstaller -F demo.py

7. 获取属性名和方法名

# 返回有序列表
__dir__()

# 返回字典形式
__dict__

六、FAQ

Q:attempted relative import with no known parent package.

相对导入问题,遇到这个问题一般就是在项目内部想要相对引用,解决方案就是在项目顶层运行模块。

Q:ValueError: attempted relative import beyond top-level package.

成功解决ValueError: attempted relative import beyond top-level package

错误原因:
相对导入的问题,试图在顶级包之外进行相对导入

解决方案:
import sys
sys.path.append("..")
import package

Q:python项目中,找不到包

# 解决办法,将项目目录加入到环境变量中
export PYTHONPATH=$(pwd):$PATHONPATH
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花花少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值