前言
python基础随记,本文涉及知识点有:映射,集合,python中__new__和__init__的区别,引用传递和值传递,线程池之ThreadPoolExecutor的简介使用。
一、映射
1)映射类型(Mapping Types)是一种关联式的容器类型,它存储了对象与对象之间的映射关系。
2)字典(dict)是Python中唯一的映射类型,它是存储了一个个 键值对(由 键 映射到 值)的关联容器。其中,键(key)必须是可哈希的Python对象,而 值(value)可以是任何Python对象。
3)字典的键必须是可哈希的。
二、集合
1)集合(set)是一个无序的不重复元素序列。
2)可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因为 { } 是用来创建一个空字典。
3)python中的set是以元素的哈希值确定位置。
三、python中__new__和__init__的区别
1)__init__方法为初始化方法,是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值。
2)__new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法。
3)就是__new__在__init__之前被调用,__new__的返回值(实例)将传递给__init__方法的第一个参数,然后__init__给这个实例设置一些参数。
四、引用传递和值传递
1)Python参数传递统一使用的是引用传递方式。因为Python对象分为可变对象(list,dict,set等)和不可变对象(number,string,tuple等)。
2)可变对象为引用传递。可变对象的值可以修改,因此可以通过修改参数值而修改原对象。类似于C语言中的引用传递。
3)不可变对象为值传递。参数变量和原变量都指向同一内存地址,但是不可变对象无法修改,所以参数的重新赋值不会影响原对象,类似于C语言中的值传递。
五、线程池之ThreadPoolExecutor
1)从 Python3.2 开始,标准库为我们提供了 concurrent.futures 模块,这个模块提供了 ThreadPoolExecutor类,这个类作用如下:
- 可以自动调度线程。
- 主线程可以获取某一个线程(或者任务的)的状态,以及返回值。
- 当一个线程完成的时候,主线程能够立即知道。
- 让多线程和多进程的编码接口一致。
2)ThreadPoolExecutor提供了四个构造方法:
3)对应上图第四个最全面的参数解释:
名称 | 类型 | 含义 |
---|---|---|
corePoolSize | int | 核心线程池大小 |
maximumPoolSize | int | 最大线程池大小 |
keepAliveTime | long | 线程最大空闲时间 |
unit | TimeUnit | 时间单位 |
workQueue | BlockingQueue< Runnable > | 线程等待队列 |
threadFactory | ThreadFactory | 线程创建工厂 |
handler | RejectedExecutionHandler | 拒绝策略 |
4)使用 ThreadPoolExecutor 来实例化线程池对象。传入max_workers参数来设置线程池中最多能同时运行的线程数目。
5)submit 函数来提交线程需要执行的任务(函数名和参数)到线程池中,并返回该任务的句柄(类似于文件、画图),注意 submit() 不是阻塞的,而是立即返回。通过 submit 函数返回的任务句柄,能够使用 done() 方法判断任务是否结束。
6)as_completed() 方法作用,上面虽然提供了判断任务是否结束的方法,但是不能在主线程中一直判断,有时候我们是得知某个任务结束了,就去获取结果,而不是一直判断每个任务有没有结束。这时就可以使用 as_completed() 方法一次取出所有任务的结果。
7)as_completed() 方法是一个生成器,在没有任务完成的时候,会阻塞,除非设置了 timeout。在有某个任务完成的时候,会 yield(让出当前任务的执行权)这个任务,就能执行for循环下面的语句,然后继续阻塞住,循环到所有的任务结束。从结果也可以看出,先完成的任务会先通知主线程。
8)常规使用线程池案例。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#线程组件
from concurrent.futures import ThreadPoolExecutor,as_completed
import time
def pingScan(self):
time.sleep(self)
print("heiheihei".format(self))
return self
executor = ThreadPoolExecutor(max_workers=2)
urls = [1,2,3]
all_task = [executor.submit(pingScan, (url)) for url in urls]
for future in as_completed(all_task):
data = future.result()
print('the result is {}'.format(data))
9)使用 with 语句,通过 ThreadPoolExecutor 构造实例。
#线程组件
from concurrent.futures import ThreadPoolExecutor,as_completed
import time
def pingScan(self):
time.sleep(self)
print("heiheihei".format(self))
return self
with ThreadPoolExecutor(max_workers=5) as executor: # 创建一个最大容纳数量为5的线程池
task1 = executor.submit(pingScan, 1)
task2 = executor.submit(pingScan, 2) # 通过submit提交执行的函数到线程池中
task3 = executor.submit(pingScan, 3)
print(f"task1: {
task1.done()}") # 通过done来判断线程是否完成
print(f"task2: {
task2.done()}")
print(f"task3: {
task3.done()}")
time.sleep(2)
print(f"task1: {
task1.done()}")
print(f"task2: {
task2.done()}")
print(f"task3: {
task3.done()}")
print(task1.result()) # 通过result来获取返回值