Python进阶、加速、打包

Python内存泄漏的原因

1、C语言开发的底层模块中出现了内存泄露
2、代码中用到了全局的 list、 dict 或其它容器,不停的往这些容器中插入对象,而忘记了在使用完之后进行删除回收
3、代码中有循环引用

Python零散知识点

  • 对象动态属性、类动态属性
  • 函数传参,不可变数据类型为值传递,可变数据类型为引用传递
  • 类名定义:首字母大写 ;其他遵循驼峰原则、见名知意
  • sys.stdout.flush()
    print默认时以‘\n’结尾,刷新缓冲然后输出。如果没有换行符就会等到程序结束才输出。
    Python – sys.stdout.flush()
import time
import sys

for i in range(5):
    print(i,end="")
    sys.stdout.flush()
    time.sleep(1)
  • 新式类(区别经典类)
    在Python3.x中,如果没有显示指明要继承的父类,则默认继承object类
  • 下划线
    __ xx __ 魔法函数
    _ xx 只能被模块内部使用,无法通过from my_module import * 导入
    xx_ 想用python关键字,又不想语法错误,如pass,可以pass_
    __xx 类的私有属性,不能外部调用,不能被子类重写
  • 容器模块collectionsdefaultdict与dict类型不同,不需要检查key是否存在;Counter计数器,可以针对某项数据进行计数;deque双端队列,可以从头/尾两端添加或删除元素;namedtuples像字典(dict)一样访问,但namedtuples是不可变的;枚举对象enum.Enum
  • Python3的解释器以"UTF-8"作为默认编码,但是这并不表示可以完全兼容中文问题。比如我们在Windows上进行开发时,Python工程及代码文件都使用的是默认的GBK编码,也就是说Python代码文件是被转换成GBK格式的字节码保存到磁盘中的。
  • 字符串类型分别为 str 和 bytes 两种,其中 str 用来表示 Unicode 字符,bytes 用来表示二进制数据。str 类型和 bytes 类型之间就需要使用 encode() 和 decode() 方法进行转换。
  • 在内存中读写,字符串使用StringIO,bytes使用BytesIO。
from io import BytesIO

byIo = BytesIO()
#参数类型为bytes
byIo.write("我的byio".encode("utf-8"))
#通过内存写入文件
with open("file.txt",mode="wb") as file:
    file.write(byIo.getvalue())
  • 虚拟环境Virtualenv 是一个工具,它能够为不同项目创建一个独立(隔离)的Python环境,而不是在全局安装所依赖的模块。
  • datatime模块重新封装了time模块,提供更多接口,提供的类有:date,time,datetime,timedelta,tzinfo。
  • is 判断是否是一个ID, == 判断内容是否一致。
  • 统计列表中元素的频率
from collections import Counter

numbers = [1, 1, 3, 2, 4, 4, 3, 6]
# 一行代码搞定求列表中每个元素出现的频率
count = Counter(numbers)
print(count)
输出:
Counter({1: 2, 3: 2, 4: 2, 2: 1, 6: 1})

  • __iter__方法、__getitem__方法(支持下标索引)都能产生可迭代对象
    __getitem__单独实现该函数,可以让这个类成为一个可迭代的对象,并且可以通过使用下标获取类中元素值下标的元素
    __call __实现该函数后,可通过类名直接调用该函数
    【Python】__iter__和__getitem__区别
  • 元类
  • 魔法函数(特殊方法)
  • 内置函数、匿名函数(lambda表达式)
  • 单例模式
  • 生成器、迭代器
  • 反射/自省
    通过hasattr、getattr、setattr、delattr四个内置函数实现的,其实这四个内置函数不只可以用在类和对象中,也可以用在模块等其他地方,只是在类和对象中用的很多
  • 列表、集合、字典生成式(推导式、解析式)
    在这里插入图片描述
    列表生成式直接生成一个多元素列表
    元组会生成迭代器

高阶函数(函数可作为参数、返回值可以是函数)

map(),filter(), reduce() ,sorted()
其中reduce函数在 python 2 是内置函数, 从python 3 开始移到了 functools 模块。
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 计算方式((((1+2)+3)+4)+5).
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。

集合set()

|并集、union
语法:set1 | set2 或者set1.union(set2)返回所有集合的元素,重复的元素只会出现一次
alpha_set = {'c', 'b'}
num_set = {1,2,'b'}
print(alpha_set | num_set)
print(num_set.union(alpha_set))
{1, 2, 'c', 'b'}
{1, 2, 'c', 'b'}

&交集、intersection
语法:set1 & set2orset1.union(set2)返回两个或更多集合中都包含的元素,即交集
alpha_set = {'c', 'b'}
num_set = {1,2,'b'}
print(alpha_set & num_set)
print(num_set.intersection(alpha_set))
{'b'}
{'b'}

-差集、difference
语法:set1 - set2orset1.difference(set2)返回的集合元素包含在set1中,但不包含在set2中
alpha_set = {'c', 'b'}
num_set = {1,2,'b'}
print(alpha_set - num_set)
print(num_set.difference(alpha_set))
{'c'}
{1, 2}

^对称差集、symmetric_difference
语法:set1 ^ set2orset1.symmetric_difference(set2)返回两个集合中不重复的元素集合
alpha_set = {'c', 'b'}
num_set = {1,2,'b'}
print(alpha_set ^ num_set)
print(num_set.symmetric_difference(alpha_set))
{'c', 1, 2}
{'c', 1, 2}

==
语法:set1 == set2判断两个集合是否相同
alpha_set = {'c', 'b'}
num_set = {1,2,'b'}
print(alpha_set == num_set)
False

父集:>>= 、issuperset
语法:set1 > set2orset1 >= set2or set1.issuperset(set2)判断set1是否包含set2
alpha_set = {'c', 'b',1,2}
num_set = {1,2,'b'}
num_set1 = {1,'b',2}
print(alpha_set > num_set)
print(num_set.issuperset(num_set1))   # issuperset相当于 >=
print(num_set > num_set1)
True
True
False

子集:<<= 、issubset
语法:set1 < set2orset1 <= set2or set1.issubset(set2)判断set2是否包含set1
alpha_set = {'c', 'b',1,2}
num_set = {1,2,'b'}
num_set1 = {1,'b',2}
print(num_set < alpha_set)
print(num_set.issubset(num_set1))   # issubset相当于 <=
print(num_set < num_set1)
True
True
False

深拷贝、浅拷贝

在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。
(1)直接赋值,默认浅拷贝传递对象的引用而已,原始列表改变,被赋值的也会做相同的改变
(2)浅拷贝,没有拷贝对象里面的子对象(列表中的列表),所以原始数据子对象改变,深拷贝里子对象也会改变
(3)深拷贝,包含对象里面的子对象的拷贝,所以原始对象的改变不会造成深拷贝里任何子元素的改变
上面例子中说的是列表(可变对象)的拷贝,那对于元组,字符等不可不对象呢?
答案是,对不可变对象,其实不存在深浅拷贝的问题。无论怎么拷贝,效果都是新建立一个指向不可变对象的指针而已。
在这里插入图片描述
Python中的赋值(复制)、浅拷贝与深拷贝

修饰器

赋予一个函数其他的功能,但又不去改变函数自身。把多个函数共性的东西抽取出来。修饰器本质是一个函数,该函数的输入输出都是函数。
1、被调函数加参数
2、修饰器加参数(再包一层函数)
3、修饰器类
内置修饰器property、 staticmethod、 classmethod,他们有个共同点,都是作用于类方法之上

闭包(区别嵌套函数)

当一个函数定义在另一个函数内,且使用到了外部函数的参数。整个代码块称为闭包。
如何创建闭包?需要满足下面三点:
1、闭包函数必须有内嵌函数
2、内嵌函数需要引用该嵌套函数上一级中的变量
3、闭包函数必须返回内嵌函数
闭包可以避免使用全局值,并提供某种形式的数据隐藏
python基础(三)内嵌函数与闭包

  • 从函数中返回函数
    在这里插入图片描述

多线程、多进程

0、Python标准库自带了两个多线程模块,分别是threading和thread,其中,thread是低级模块,threading是对thread的封装
1、父子进程会独立运行,互不干扰。而且父子进程的调用需要系统来调度。
2、默认情况下,python产生的线程是非守护线程( setDaemon(False))即主线程不会等待子线程完成任务,而是异步执行程序,把任务交给子线程之后,主线程继续往下执行,遇到新的任务后,主线程可以选择自己执行,也可以再次产生新的子线程去执行,当主线程执行完所有的程序后,这个时候主线程并不会退出,也就是不会销毁,直到所有的子线程完成了各自的任务后才自动销毁。
3、守护线程 (setDaemon(True))即主线程一旦结束,就会退出,也就是自动销毁,不会等待子线程,主线程一旦销毁,则所有的子线程也会跟着销毁,无论任务是否执行完成。
4、同步线程(join)当主线程遇到同步线程的时候,即遇到join()的时候会等待(即主线程进入堵塞状态,无法继续前行)所有的同步线程执行完毕之后,主线程才继续往下走,这里说的同步是针对主线程而言,意思是遇到join的时候,主线程会被堵塞,不会继续往下执行其它程序,而是等待join的线程执行完毕后再往下执行,而多个join的子线程之间是并行的,即互不影响。
5、互斥锁,多个线程共同对某个数据修改,为了保证数据的正确性,需要使用互斥锁对多个线程进行同步,限制当一个线程正在访问数据时,其他只能等待,直到前一线程释放锁。对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。也可以使用with lock。
进程与线程

线程池、进程池

1、由于线程预先被创建并放入线程池中,同时处理完当前任务之后并不销毁而是被安排处理下一个任务,因此能够避免多次创建线程,从而节省线程创建和销毁的开销,能带来更好的性能和系统稳定性。
2、 ThreadPoolExecutor 用于创建线程池,而 ProcessPoolExecutor 用于创建进程池。
3、如果使用线程池/进程池来管理并发编程,那么只要将相应的 task 函数提交给线程池/进程池,剩下的事情就由线程池/进程池来搞定。程序将 task 函数提交(submit)给线程池后,submit 方法会返回一个 Future 对象,Future 类主要用于获取线程任务函数的返回值。由于线程任务会在新线程中以异步方式执行,因此,线程执行的函数相当于一个“将来完成”的任务,所以 Python 使用 Future 来代表。

  • 返回子进程的结果:多进程共享全局变量之Manager()、进程通信
    在这里插入图片描述

python加速PyPy、Numba 、Cython、Pyjion

优化 Python 性能:PyPy、Numba 与 Cython,谁才是目前最优秀的 Python 运算解决方案?
Cython基本用法
用Cython加速Python到“起飞”
java、c/c++ 、python 等性能比较 杂谈(整理)
pypy真的能让python比c还快?
numba从入门到精通(1)—为什么numba能够加速
用Cython和PyPy提升Python性能
python性能优化的比较:numba,pypy, cython
java为什么比python快
微软发布 Python 的 JIT 编译器:Pyjion 文末包邮送新书
A drop-in JIT Compiler for Python 3.10
win10 + pypy3解释器的的安装及配置 以及第三方库的安装

Python调用c代码ctypes、swig、cython、pybind11

如果遇到需要 Python C/C++ 混合编程的需求,尽量使用 Pybind11 或 Cython,ctypes 和 Python-C-API 方案尽量不考虑。
Pybind11
在这里插入图片描述

python加密

python打包

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值