一、Python中if name == ‘main’:的作用和原理
if __name__ == '__main__':
每个python文件都包含内置变量-name-如果被当前脚本执行时则相当于文件名(包括后缀名.py),当被import到其他脚本中相当于模块的名称(不包括后缀名.py)
而 “main” 始终指当前执行模块的名称(包含后缀.py)。进而当模块被直接执行时,name == ‘main’ 结果为真。
详细见https://blog.csdn.net/heqiang525/article/details/89879056
二、使用步骤
1.引入库
代码如下(示例):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
2.多线程
代码如下:
import asyncio
async def do_some_work(x): #注意!是async不是asyncio
print("Waiting " + str(x))
await asyncio.sleep(x)
loop = asyncio.get_event_loop() #生成一个loop对象
loop.run_until_complete(do_some_work(3)) #执行loop(放置任务)
get_event_loop() 只会在主线程帮您创建新的 event loop
我们想运用协程,首先要生成一个loop对象,然后loop.run_xxx()就可以运行协程了,而如何创建这个loop, 方法有两种:对于主线程是loop=get_event_loop(). 对于其他线程需要首先loop=new_event_loop(),然后set_event_loop(loop)。
new_event_loop()是创建一个event loop对象,而set_event_loop(eventloop对象)是将event loop对象指定为当前协程的event loop,一个协程内只允许运行一个event loop,不要一个协程有两个event loop交替运行。
综上: 一个协程任务,不能运行在两个及两个以上不同的循环中。一个循环体可以运行多个不同的协程任务。
引用https://blog.csdn.net/whatday/article/details/106885916
所以多线程的初步想法就是,引入asyncio模块,定义函数,创建event loop对象,建立任务库(上述代码未出现),放置任务
3.time()
time函数有很多作用和语法,但是今天我只用了time.time()来计时。更多用法见 https://blog.csdn.net/daydayjump/article/details/80801016
time.time()是在开始和结束时用来求程序运行的时间差值
4.json()
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式。Python3 中可以使用 json 模块来对 JSON 数据进行编解码,它主要提供了四个方法: dumps、dump、loads、load。
dump和dumps
dump和dumps对python对象进行序列化。将一个Python对象进行JSON格式的编码。
dump函数:
json.dump(obj, fp, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
1
obj: 表示是要序列化的对象。
fp: 文件描述符,将序列化的str保存到文件中。json模块总是生成str对象,而不是字节对象;因此,fp.write()必须支持str输入。
skipkeys: 默认为False,如果skipkeysTrue,(默认值:False),则将跳过不是基本类型(str,int,float,bool,None)的dict键,不会引发TypeError。
ensure_ascii: 默认值为True,能将所有传入的非ASCII字符转义输出。如果ensure_ascii为False,则这些字符将按原样输出。
check_circular:默认值为True,如果check_circular为False,则将跳过对容器类型的循环引用检查,循环引用将导致OverflowError。
allow_nan: 默认值为True,如果allow_nan为False,则严格遵守JSON规范,序列化超出范围的浮点值(nan,inf,-inf)会引发ValueError。 如果allow_nan为True,则将使用它们的JavaScript等效项(NaN,Infinity,-Infinity)。
indent: 设置缩进格式,默认值为None,选择的是最紧凑的表示。如果indent是非负整数或字符串,那么JSON数组元素和对象成员将使用该缩进级别进行输入;indent为0,负数或“”仅插入换行符;indent使用正整数缩进多个空格;如果indent是一个字符串(例如“\t”),则该字符串用于缩进每个级别。
separators: 去除分隔符后面的空格,默认值为None,如果指定,则分隔符应为(item_separator,key_separator)元组。如果缩进为None,则默认为(’,’,’:’);要获得最紧凑的JSON表示,可以指定(’,’,’:’)以消除空格。
default: 默认值为None,如果指定,则default应该是为无法以其他方式序列化的对象调用的函数。它应返回对象的JSON可编码版本或引发TypeError。如果未指定,则引发TypeError。
sort_keys: 默认值为False,如果sort_keys为True,则字典的输出将按键值排序。
dumps函数:
json.dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
1
dumps函数不需要传文件描述符,其他的参数和dump函数的一样。
load和loads
load和loads反序列化方法,将json格式数据解码为python对象。
load函数:
json.load(fp, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
1
fp: 文件描述符,将fp(.read()支持包含JSON文档的文本文件或二进制文件)反序列化为Python对象。
object_hook: 默认值为None,object_hook是一个可选函数,此功能可用于实现自定义解码器。指定一个函数,该函数负责把反序列化后的基本类型对象转换成自定义类型的对象。
parse_float: 默认值为None,如果指定了parse_float,用来对JSON float字符串进行解码,这可用于为JSON浮点数使用另一种数据类型或解析器。
parse_int: 默认值为None,如果指定了parse_int,用来对JSON int字符串进行解码,这可以用于为JSON整数使用另一种数据类型或解析器。
parse_constant:默认值为None,如果指定了parse_constant,对-Infinity,Infinity,NaN字符串进行调用。如果遇到了无效的JSON符号,会引发异常。
如果进行反序列化(解码)的数据不是一个有效的JSON文档,将会引发 JSONDecodeError异常。
loads函数:
json.loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
1
s: 将s(包含JSON文档的str,bytes或bytearray实例)反序列化为Python对象。
encoding: 指定一个编码的格式。
loads也不需要文件描述符,其他参数的含义和load函数的一致。
格式转化表
JSON中的数据格式和Python中的数据格式转化关系如下:
JSON Python
object dict
array list
string str
number (int) int
number (real) float
true True
false False
null None
实例:
dump和dumps
import json
# dumps可以格式化所有的基本数据类型为字符串
data1 = json.dumps([]) # 列表
print(data1, type(data1))
data2 = json.dumps(2) # 数字
print(data2, type(data2))
data3 = json.dumps('3') # 字符串
print(data3, type(data3))
dict = {"name": "Tom", "age": 23} # 字典
data4 = json.dumps(dict)
print(data4, type(data4))
with open("test.json", "w", encoding='utf-8') as f:
# indent 超级好用,格式化保存字典,默认为None,小于0为零个空格
f.write(json.dumps(dict, indent=4))
json.dump(dict, f, indent=4) # 传入文件描述符,和dumps一样的结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
得到的输出结果如下:格式化所有的数据类型为str类型
[] <class 'str'>
2 <class 'str'>
"3" <class 'str'>
{"name": "Tom", "age": 23} <class 'str'>
1
2
3
4
test.json中的内容
{
"name": "Tom",
"age": 23
}
1
2
3
4
load和loads
import json
dict = '{"name": "Tom", "age": 23}' # 将字符串还原为dict
data1 = json.loads(dict)
print(data1, type(data1))
with open("test.json", "r", encoding='utf-8') as f:
data2 = json.loads(f.read()) # load的传入参数为字符串类型
print(data2, type(data2))
f.seek(0) # 将文件游标移动到文件开头位置
data3 = json.load(f)
print(data3, type(data3))
1
2
3
4
5
6
7
8
9
10
11
12
运行结果如下:
{'name': 'Tom', 'age': 23} <class 'dict'>
{'name': 'Tom', 'age': 23} <class 'dict'>
{'name': 'Tom', 'age': 23} <class 'dict'>
1
2
3
常见的错误:
读取多行的JSON文件
假如要读取一个多行的JSON文件:
{"坂": ["坂5742"]}
{"构": ["构6784"]}
{"共": ["共5171"]}
{"钩": ["钩94a9"]}
{"肮": ["肮80ae"]}
{"孤": ["孤5b64"]}
1
2
3
4
5
6
如果直接使用:
with open(json_path, 'r') as f:
json_data = json.load(f)
1
2
就会报错:抛出异常JSONDecodeError。
json.decoder.JSONDecodeError: Extra data: line 2 column 1 (char 17)
1
表示数据错误,数据太多,第2行第一列
因为json只能读取一个文档对象,有两个解决办法
1、单行读取文件,一次读取一行文件。
2、保存数据源的时候,格式写为一个对象。
单行读取文件:
with open(json_path, 'r') as f:
for line in f.readlines():
json_data = json.loads(line)
1
2
3
但是这种做法还有个问题,如果JSON文件中包含空行,还是会抛出JSONDecodeError异常
json.decoder.JSONDecodeError: Expecting value: line 2 column 1 (char 1)
1
可以先处理空行,再进行文件读取操作:
for line in f.readlines():
line = line.strip() # 使用strip函数去除空行
if len(line) != 0:
json_data = json.loads(line)
1
2
3
4
合并为一个对象
将json文件处理成一个对象文件。
{"dict": [
{"坂": ["坂5742"]},
{"构": ["构6784"]},
{"共": ["共5171"]},
{"钩": ["钩94a9"]},
{"肮": ["肮80ae"]},
{"孤": ["孤5b64"]}
]}
1
2
3
4
5
6
7
8
然后再用:
with open(json_path, 'r') as f:
json_data = json.loads(f.read())
1
2
总结:
json.dumps 将 Python 对象编码成 JSON 字符串
json.loads 将已编码的 JSON 字符串解码为 Python 对象
json.dump和json.load,需要传入文件描述符,加上文件操作。
JSON内部的格式要注意,一个好的格式能够方便读取,可以用indent格式化。
原文 https://blog.csdn.net/whjkm/article/details/81159888
简单来说,json就是将JSON类的数据通过函数进行解码,进行各格式间的转换
5.进程池()
python 进程池pool简单使用
平常会经常用到多进程,可以用进程池pool来进行自动控制进程,下面介绍一下pool的简单使用。
需要主动是,在Windows上要想使用进程模块,就必须把有关进程的代码写if name == ‘main’ :语句的下面,才能正常使用Windows下的进程模块。Unix/Linux下则不需要。
Pool类
Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,
才会创建新的进程来执行这些请求。
下面介绍一下multiprocessing 模块下的Pool类下的几个方法:
1、apply()
函数原型:apply(func[, args=()[, kwds={}]])
该函数用于传递不定参数,同python中的apply函数一致,主进程会被阻塞直到函数执行结束(不建议使用,并且3.x以后不在出现)。
2、apply_async
函数原型:apply_async(func[, args=()[, kwds={}[, callback=None]]])
与apply用法一致,但它是非阻塞的且支持结果返回后进行回调。
3、map()
函数原型:map(func, iterable[, chunksize=None])
Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到结果返回。
注意:虽然第二个参数是一个迭代器,但在实际使用中,必须在整个队列都就绪后,程序才会运行子进程。
4、map_async()
函数原型:map_async(func, iterable[, chunksize[, callback]])
与map用法一致,但是它是非阻塞的。其有关事项见apply_async。
5、close()
关闭进程池(pool),使其不在接受新的任务。
6、terminal()
结束工作进程,不在处理未处理的任务。
7、join()
主进程阻塞等待子进程的退出, join方法要在close或terminate之后使用。