Python
Python
一、项目打包
常见的打包工具有哪些 ?
- distutils
- setuptools
什么是setuptools?
- setuptools是distutils的增强版,并不在标准库中,拓展了很多功能,大部分用户都会选择setuptools模块
源码包与二进制包有什么区别?
源码包:
- 安装过程:先解压,再编译,最后安装,所以跨平台,速度比较慢
二进制包:
省去了编译的过程,直接解压安装;但是由于不同平台编译出来的包无法通用,所以在发布时需要先编译好多个平台的包:
常见格式:
格式 后缀 egg .egg wheel .whl egg和whl有何区别?
- Egg是setuptools在2004年引入的,Wheel则是在2012年才定义,Wheel的出现是为了替代Egg,本事是一个Zip包,现在被认为是标准的Python二进制包格式
- wheel包可以通过pip安装,只不过需要首先安装wheel模块:
pip install wheel
setup.py的编写:
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
from __future__ import print_function
from setuptools import setup, find_packages
data_files = []
setup(
name='capbac',
version='1.0',
description='Sawtooth CapBAC',
author='kappanneo',
# 项目主页
url='https://github.com/kappanneo/sawtooth-capbac',
# 指的是你要安装的包
packages=find_packages(),
# 指明当前模块现需要依赖哪些包,若环境中没有,则从pypi中下载
install_requires=[
'aiohttp',
'aiocoap'
'colorlog',
'protobuf',
'sawtooth-sdk',
'sawtooth-signing',
'PyYAML',
],
#指明目的目录和源文件路径
data_files=data_files,
# 用来支持自动生成脚本,安装后自动生成/usr/bin/capbac的可执行文件
# 该文件入口指向capbac_cli.py的main_wrapper函数
entry_points={
'console_scripts': [
'capbac = capbac_cli:main_wrapper',
]
})使用setup.py构建包:
构建源码发布包:
构建
1python setup.py sdist
安装
1eash_install xxx.tar.gz
构建二进制分发包:
Windows上可以构建成exe这样的二进制软件包:
1python setup.py bdist_wininst
Linux上构建rpm包:
1python setup.py bdist_rpm
Linux上构建egg包:
1python setup.py bdist_egg
在多个平台构建:
1python setup.py bdist
使用setup.py安装包:
1
2python setup.py install 安装到系统全局环境
python setup.py develop 不会真正安装包,而是在环境变量中创建一个软链接,便于调试参考资料:https://blog.csdn.net/calvinpaean/article/details/113580458
二、日期模块
time
当前时间戳:
1
2
3
import time
print(time.time())
# 1684753413.0579932时间戳转时间:
1
2
3
4
5
6
import datetime
import time
t1 = time.time()
t2 = datetime.datetime.fromtimestamp(t1)
print(t2.isoformat())输出当前时间的字符串
1
2
3
import time
print(time.strftime("%Y-%m-%d-->%H:%M:%S"))
# 2023-05-22-->19:06:59将字符串解析为datatime对象
1
2
3
4
5
6
from datetime import datetime
date_str = '2021-05-22'
date_obj = datetime.strptime(date_str, '%Y-%m-%d')
print(date_obj)
# 2021-05-22 00:00:00
参考:https://geekpy.github.io/2018/08/12/python_time/
三、Socket编程
当客户端执行
sock.close()
,会向服务器发送FIN包,此时服务端的conn.recv(1024)
才会返回空字符串;如果直接发送空字符串,conn.recv(1024)
并不会返回空字符串,而是继续阻塞等待。服务端同理,执行
conn.close()
后,客户端的sock.recv(1024)
也会返回空字符串注意:当任意一段执行
close()
后,另一端都要再次执行close()
socket.send()
受制于MTU,不一定发送完给定的数据
socket.sendall()
若发送完则返回None,失败则抛出异常
client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import socket
# 创建TCP套接字对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# socket.AF_INET为ipv4,socket.SOCK_STREAM为TCP套接字
# 连接服务器
sock.connect(('192.168.126.140', 8083))
while True:
# 发送数据到服务器并接收响应
sock.sendall(b'asd')
data = sock.recv(1024)
if not data:
print("fuck!~")
sock.close()
break
# 打印从服务器接收到的响应
print(data.decode())
# 关闭套接字
server.py
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
import socket
# 创建TCP套接字对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定IP地址和端口号
sock.bind(('localhost', 8080))
# 开始监听客户端连接
sock.listen(1)
# 1表示最多允许排队的连接数为1个
# 等待客户端连接
conn, addr = sock.accept()
# 接收来自客户端的数据并发送回去
print(addr)
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data + b'fuck')
# 关闭套接字
conn.close()
sock.close()
四、日志
1 |
|
五、参数解析Argparser
argparse模块帮助编写命令行接口
默认值参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# coding:utf-8
import argparse
parser = argparse.ArgumentParser(description='命令行中传入一些数字') # 参数解析器
parser.add_argument('-a', type=int, nargs='+', default=123, help='加数a')
parser.add_argument('-b', type=int, nargs='+', default=456, help='加数a')
args = parser.parse_args()
print(args.a[0]+args.b[0])
print(args.a)
"""
567
[123, 222, 22]
"""必须参数
required=True
补充说明
当-和--同时出现的时候 python默认后者为参数名
1
2
3
4
参数nargs:
nargs='*' 表示参数可设置零个或多个
nargs='+' 表示参数可设置一个或多个
nargs='?' 表示参数可设置零个或一个参考
https://zhuanlan.zhihu.com/p/56922793
https://baijiahao.baidu.com/s?id=1718013777590980266&wfr=spider&for=pc
六、Pandas
6.1 读取数据
1 |
|
6.2 数据结构
DataFrame
二维数据,类似表格,有列名columns和行名index
从DataFrame中读取一行或者一列:Series,其余仍是DataFrame
DataFrame由多个Series组成,无论是行还是列,单独拆分出来都是一个Series
若查询一列的话:直接把DataFrame当作字典即可
若查询一行的话:需要用到loc
1 |
|
Series
一维数据,一行或者一列
1 |
|
6.3 查询数据
loc() :根据标签名进行查询
iloc() :根据索引序列查询
二者均可以用切片
其中loc可以使用条件表达式进行查询
6.4 新增数据列
直接赋值
data[:, "new_column"] = data["col1"] + data["col2"]
apply方法
axis:0为行1为列,指定了那个axis,这个axis就要动起来
1
2
3def get_content():
return content
data.loc[:, "new_column"] = data.apply(get_content, axis = 1)assign方法
1
2
3new_data = data.assign(
new_cloumn = lambda x: x["col1"]*33
)按条件选择分组分别赋值
1
2
3data["new_clo"] = ""
data.loc[条件1,"new_col"] = value1
data.loc[条件2,"new_col"] = value2进度:https://www.bilibili.com/video/BV1UJ411A7Fs?p=6&vd_source=bf133d296119691c661008e881da330a&t=40.3
6.5 输出excel
1 |
|
6.6 其他
设置不隐藏列数
1 |
|
筛选数据
1 |
|
合并数据
1 |
|
更改列的数据类型
1 |
|
筛选数据-以xxx开头
1 |
|
排序
1 |
|
除去为NaN的数据
1 |
|
重构索引
1 |
|
统计数量
1 |
|
删除某一列
1 |
|
筛选出目标数值在某一个列表内的数据
1 |
|
乱序
1 |
|
计算若干列的均值和方差
1 |
|
计算若干分组的均值和方差
1 |
|
七、装饰器
闭包函数
一个函数,其参数和返回值都是函数,闭包函数的返回值是对传入函数进行增强后的结果
装饰器
本质是函数闭包,修改其他函数的功能,有助于代码更简短
注意:装饰器只在第一次调用前起作用,只增强一次
无参,无返回值
1 |
|
eg2:使用functools.wraps
@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。这可以让我们在装饰器里面访问在装饰之前的函数的属性。--菜鸟教程
1 |
|
有参,有返回值
若被修饰函数有参数,则需在装饰器内定义wrapper时加入参数如"*args",wrapper内调用被修饰函数也要加入参数,另外,若被修饰函数有返回值,则在wrapper里默认是无效的,需要定义一个临时变量接受其返回值
1 |
|
八、Collections
8.1 Deque
官方文档:https://docs.python.org/zh-cn/3/library/collections.html?highlight=deque#collections.deque
说明:双向队列
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from collections import deque
d = deque()
d.append(1)
d.append(2)
d.append(3)
print(d)
d.appendleft(11)
d.appendleft(22)
d.appendleft(33)
print(d)
print(d.pop())
print(d.popleft())
print(d)
"""
deque([1, 2, 3])
deque([33, 22, 11, 1, 2, 3])
3
33
deque([22, 11, 1, 2])
"""
8.2 Counter
官方文档:https://docs.python.org/zh-cn/3/library/collections.html?highlight=deque#collections.Counter
说明:可以很方便的用来计数
使用样例1(计数):
1
2
3
4
5
6
7
from collections import Counter
cnt = Counter()
for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']:
cnt[word] += 1
print(cnt)
# Counter({'blue': 3, 'red': 2, 'green': 1})使用样例2(计数):
1
2
3
4
5
from collections import Counter
cnt = Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])
print(cnt)
# Counter({'blue': 3, 'red': 2, 'green': 1})使用样例3(筛选频率最高的前n项):
1
2
3
4
5
from collections import Counter
cnt = Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])
print(cnt.most_common(2))
# [('blue', 3), ('red', 2)]
8.3 heapq
官方文档:https://docs.python.org/zh-cn/3/library/heapq.html
heapq直接存放在标准库中,不在Collections下
说明:这个模块提供了堆队列的算法,也称为优先队列算法
将列表转换为小顶堆:
1
2
3
4
5
import heapq
li = [1, 3, -1, 4, 5, 89]
heapq.heapify(li)
print(li)插入和弹出元素:
1
2
3
4
5
6
7
import heapq
li = [1, 3, -1, 4, 5, 89]
heapq.heapify(li)
heapq.heappush(li, 33)
least_ele = heapq.heappop(li)
print(least_ele)插入某元素后立马弹出根元素:
1
2
3
4
5
6
import heapq
li = [1, 3, -1, 4, 5, 89]
heapq.heapify(li)
ele = heapq.heappushpop(li, 33)
print(ele)弹出根元素后插入某元素:
1
2
3
4
5
6
import heapq
li = [1, 3, -1, 4, 5, 89]
heapq.heapify(li)
ele = heapq.heapreplace(li, 33)
print(ele)
九、Pytorch
9.0 基础知识
torch.tensor与torch.Tensor有何不同?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import torch
# torch.tensor会自动判断类型
x = torch.tensor([1, 2])
print(torch.typename(x))
# 显式指明数据类型
y = torch.tensor([1, 2], dtype=torch.float)
print(torch.typename(y))
# torch.Tensor默认返回torch.FloatTensor类型
z = torch.Tensor([1, 2])
print(torch.typename(z))
"""
torch.LongTensor
torch.FloatTensor
torch.FloatTensor
"""
9.1 矩阵相乘
参考资料:https://www.bilibili.com/video/BV1za411S7sA?t=3.8
不考虑数学意义上的矩阵乘法:
torch.mul()
等价于*
数学意义上的矩阵相乘:
torch.dot()
:一维torch.mm()
:二维torch.bmm()
:三维torch.matmul(),等价于@
:通用
*运算
两个矩阵按位相乘,和矩阵的乘法运算不同
1
2
3
4
5
6
7
8
import torch
x = torch.tensor([1, 2])
y = torch.tensor([2])
print(x * y) # tensor([2, 4])
x = torch.tensor([1, 2])
y = torch.tensor([3, 4])
print(x * y) # tensor([3, 8])
torch.dot()
只支持一维的矩阵相乘,注意,一维矩阵的转置实际上是没有意义的
1
2
3
4
5
6
import torch
x = torch.tensor([1, 2])
y = torch.tensor([2, 4])
print(torch.dot(x, y)) # tensor(10)
print(torch.dot(x.t(), y)) # tensor(10)
torch.mm()
只支持二维的矩阵相乘
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import torch
x = torch.tensor([[1, 2],
[1, 2]])
y = torch.tensor([[1, 2],
[3, 4]])
print(torch.mm(x, y))
print(torch.mm(x.t(), y))
"""
tensor([[ 7, 10],
[ 7, 10]])
tensor([[ 4, 6],
[ 8, 12]])
"""
torch.bmm()
类似torch.mm(),只支持三维矩阵相乘
torch.matmul()(等价于@)
功能最强,支持广播
1
2
3
4
5
6
import torch
x = torch.tensor([[1, 2],
[1, 2]])
y = torch.tensor([1, 2])
print(x @ y) # tensor([5, 5])
十、Functools
reduce:当需要对一个可迭代对象做累积操作时使用
1 |
|
十一、包和模块
https://www.bilibili.com/video/BV194411r7a8?t=30.7
模块:为了提高代码的重用价值,将一组功能写进一个单独的.py文件中,这个.py文件就是一个模块
包:一个有层次的目录结构,定义了n个模块或子包,目录下一定有__init__.py
文件
库:参照其他语言的叫法,可以是模块也可以是包
- import与from
import的最后是一个模块,比如import A.B.C中的C。如果只使用import不使用from的话,可以使用别名简化前缀,或者增加拓展性,比如import A as p与import B as p, 可以根据需求从A和B之间选择,但是最终都是p。
如果只import包,默认不会导入包的内容。我们可以在__init__.py
文件中指明默认import哪些模块(要使用绝对路径)
- from注意事项
from A import B中A的范围一定大于B,其中B一定要达到最简化,也就是把路径尽可能放在A,其中访问取值:包>模块>模块资源
我们可以通过from 模块 import *
的方式导入模块的所有资源,但是模块中需要定义__all__=['A','B']
,其中列表内是所有资源。若没有__all__
,则会导入所有非下划线开头的资源
当然from 包 import *
也可以,但是需要在__init__.py
中指明__all__
变量,列表里面存放模块名
https://www.bilibili.com/video/BV194411r7a8?t=241.3&p=15
十二、Numpy
从正态分布中随机取值
1 |
|
十三、其它
按照不同的概率选择元素
1 |
|