Python3中的json模块使用详解


Posted in Python onMay 05, 2018

1. 概述

JSON (JavaScript Object Notation)是一种使用广泛的轻量数据格式. Python标准库中的json模块提供了JSON数据的处理功能.

Python中一种非常常用的基本数据结构就是字典(Dictionary). 它的典型结构如下:

d = {
'a': 123,
'b': {
'x': ['A', 'B', 'C']
}
}

而JSON的结构如下:

{
"a": 123,
"b": {
"x": ["A", "B", "C"]
}
}

可以看到, Dictionary和JSON非常接近, 而Python中的json库提供的主要功能, 也是两者之间的转换.

2. 读取JSON

json.loads方法可以将包含了一个JSON数据的str, bytes或者bytearray对象, 转化为一个Python Dictionary. 它的完型接口签名如下:

json.loads(s, *, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)

2.1 最简单的例子

json.loads最基本的使用方式就是将一个包含JSON数据的str传递给这个方法:

>>> json.loads('{"a": 123}')
{'a': 123}

注意

在Python中, str值可以放在一对单引号中, 也可以放在一对双引号中:

>>> 'ABC' == "ABC"
True

所以, 在定义Dictionary的str类型的键和值的时候, 使用单引号或者双引号都是合法和等价的:

>>> {"a": 'ABC'} == {'a': "ABC"}
True

但是, 在JSON中, 字符串数据只能放在双引号中, 因而json.loads方法处理的字符串的JSON内容中, 字符串必须使用双引号. 否则就会发生解码错误:

>>> json.loads("{'a': 123}")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 354, in loads
return _default_decoder.decode(s)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 355, in raw_decode
obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)

如果被处理的Python字符串是包含在双引号中的, 那么JSON中的双引号就需要转义:

>>> json.loads("{\"a\": 123}")
{'a': 123}

2.2 bytes和bytearray数据

对于内容是JSON数据的bytes和bytearray, json.loads方法也可以处理:

>>> json.loads('{"a": 123}'.encode('UTF-8'))
{'a': 123}
>>> json.loads(bytearray('{"a": 123}', 'UTF-8'))
{'a': 123}

2.3 编码格式

json.loads的第二个参数是encoding没有实际作用.

由于Python 3中str类型总是使用UTF-8编码, 所以s参数为str类型时, json.loads方法自动使用UTF-8编码. 并且, str不能以BOM字节开头.

当s参数为bytes或者bytearray时, json.loads方法会自动判断为UTF-8, UTF-16还是UTF-32编码. 默认也是将其按照UTF-8编码转化为str对象进行后续处理.

2.4 数据类型转换

JSON可以表示四种主类型数据

  • 1.字符串 string
  • 2.数字 number
  • 3.布尔类 boolean
  • 4.空值 null

以及两结数据结构

  • 1.对象 object
  • 2.数组 array

默认实现中, JSON和Python之间的数据转换对应关系如下表:

JSON Python
object dict
array list
string str
number (int) int
number (real) float
true True
false False
null None

实际转换情况如下例:

>>> json.loads("""
... {
... "obj": {
... "str": "ABC",
... "int": 123,
... "float": -321.89,
... "bool_true": true,
... "bool_false": false,
... "null": null,
... "array": [1, 2, 3]
... }
... }""")
{'obj': {'str': 'ABC', 'int': 123, 'float': -321.89, 'bool_true': True, 'bool_false': False, 'null': None, 'array': [1, 2, 3]}}

对于JSON中数字number类型的数据, 有以下几点需要注意:

1.JSON中的实数real number类型的精度不能超过Python中的float类型的精度范围, 否则就有精度损失. 如下例:

>>> json.loads('3.141592653589793238462643383279')
3.141592653589793

2.JSON标准不包括非数字NaN, 正无穷Infinity和负无穷-Infinity, 但是json.loads方法默认会将JSON字符串中的NaN, Infinity, -Infinity转化为Python中的float('nan'), float('inf')和float('-inf'). 注意, 这里JSON中的NaN, Infinity, -Infinity必须大小写正确并且拼写完整. 如下例

>>> json.loads('{"inf": Infinity, "nan": NaN, "ninf": -Infinity}')
{'inf': inf, 'nan': nan, 'ninf': -inf}

2.5 自定义JSON对象转换类型

json.loads默认将JSON中的对象数据转化为Dictionary类型, object_hook参数可以用来改变构造出的对象.

object_hook接受一个函数, 这个函数的输入参数为JSON中对象数据转化出的Dictionary对象, 其返回值则为自定义的对象. 如下例所示:

>>> class MyJSONObj:
... def __init__(self, x):
... self.x = x
...
>>> def my_json_obj_hook(data):
... print('obj_hook data: %s' % data)
... return MyJSONObj(data['x'])
...
>>> result = json.loads('{"x": 123}', object_hook=my_json_obj_hook)
obj_hook data: {'x': 123}
>>> type(result)
<class '__main__.MyJSONObj'>
>>> result.x
123

当JSON中的对象有嵌套时, json.loads方法会按照深度优先的方式遍历对象树, 将各层的对象数据传递给object_hook. 叶节点的JSON对象构造出的Python对象, 会作为父节点的一个值, 传递给父节点的object_hook方法. 如下例:

>>> class MyJSONObj:
... def __init__(self, x, y):
... self.x = x
... self.y = y
...
>>> def my_json_obj_hook(data):
... print('obj_hook data: %s' % data)
... return MyJSONObj(**data)
...
>>> result = json.loads('{"x": {"x": 11, "y": 12}, "y": {"x": 21, "y":22}}', object_hook=my_json_obj_hook)
obj_hook data: {'x': 11, 'y': 12}
obj_hook data: {'x': 21, 'y': 22}
obj_hook data: {'x': <__main__.MyJSONObj object at 0x10417ef28>, 'y': <__main__.MyJSONObj object at 0x10417ed68>}

除了object_hook参数以外, 还有一个object_pairs_hook参数. 这个参数同样可以用来改变json.loads方法构造出的Python对象的类型. 这个参数和object_hook的不同, 在于传入的方法所接收到的输入数据不是一个Dictionary, 而是一个包含tuple的list. 每个tuple都有两个元素, 第一个元素是JSON数据中的键, 第二个元素是这个键对应的值. 如JSON对象

{
"a": 123,
"b": "ABC"
}

对应的输入数据是

[
('a': 123),
('b', 'ABC')
]

当调用json.loads方法时, 同时指定object_hook和object_pairs_hook, object_pairs_hook会覆盖object_hook参数.

2.6 自定义JSON数字转换类型

默认实现中, JSON中的实数被转换为Python的float类型, 整数被转换为int或者long类型. 类似object_hook, 我们可以通过parse_float和parse_int参数指定自定义的转换逻辑. 这两个方法的输入参数为表示JSON实数或者整数的字符串. 下例中, 我们将实数转换为numpy.float64, 将整数转换为numpy.int64:

>>> def my_parse_float(f):
... print('%s(%s)' % (type(f), f))
... return numpy.float64(f)
...
>>> def my_parse_int(i):
... print('%s(%s)' % (type(i), i))
... return numpy.int64(i)
...
>>> result = json.loads('{"i": 123, "f": 321.45}', parse_float=my_parse_float, parse_int=my_parse_int)
<type 'str'>(123)
<type 'str'>(321.45)
>>> type(result['i'])
<type 'numpy.int64'>
>>> type(result['f'])
<type 'numpy.float64'>

2.6.1 自定义NaN, Infinity和-Infinity转换类型

由于标准JSON数据不支持NaN, Infinity和-Infinity, 所以parse_float并不会接收到这几个值. 当需要自定义这几个值转换的对象的时候, 就需要使用另外一个接口parse_constant. 比如下例中, 将这几个值同样转换为numpy.float64类型:

>>> def my_parse_constant(data):
... print('%s(%s)' % (type(data), data))
... return numpy.float64(data)
...
>>> result = json.loads('{"inf": Infinity, "nan": NaN, "ninf": -Infinity}', parse_constant=my_parse_constant)
<type 'str'>(Infinity)
<type 'str'>(NaN)
<type 'str'>(-Infinity)
>>> result['inf']
inf
>>> type(result['inf'])
<type 'numpy.float64'>

2.7 非对象顶级值

根据JSON规范, 一个JSON数据中, 可以只包含一个值, 而不是一个完整的对象. 这个值可以是一个字符串, 一个数字, 布尔值, 空值, 或者一个数组. 除了这三种JSON规范中给出的类型, 还可以是NaN, Infinity或者-Infinity:

>>> json.loads('"hello"')
'hello'
>>> json.loads('123')
123
>>> json.loads('123.34')
123.34
>>> json.loads('true')
True
>>> json.loads('false')
False
>>> print(json.loads('null'))
None
>>> json.loads('[1, 2, 3]')
[1, 2, 3]

2.8 重复键名

在同一层级JSON对象中, 不应当出现重复的键名, 不过JSON规范中没有给出这种情况的处理标准. 在json.loads中, 当JSON数据中有重复键名, 则后面的键值会覆盖前面的:

>>> json.loads('{"a": 123, "b": "ABC", "a": 321}')
{'a': 321, 'b': 'ABC'}

2.9 处理JSON数据文件

当JSON数据是保存在一个文件中的时候, json.load方法可以用来从这个文件中读取数据, 并转换为Python对象. json.load方法的第一个参数就是指向JSON数据文件的文件类型对象.

比如/tmp/data.json文件的内含如下:

{
"a": 123,
"b": "ABC"
}

可以使用下例中的代码来读取并转化文件中的JSON数据:

>>> with open('/tmp/data.json') as jf:
... json.load(jf)
...
{u'a': 123, u'b': u'ABC'}

除了文件类型的对象, 只要是实现了read方法的类文件对象, 都可以作为fp参数, 比如下例中的io.StringIO:

>>> sio = io.StringIO('{"a": 123}')
>>> json.load(sio)
{'a': 123}

json.load方法的其他参数的意义和使用方法和上文中的json.loads相同, 这里不再赘述.

3 生成JSON

json.dumps方法可以将Python对象转换为一个表示JONS数据的字符串. 它的完整接口签名如下:

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)

它的第一个参数obj即为要转换的数据对象.

>>> json.dumps({'a': 123, 'b': 'ABC'})
'{"a": 123, "b": "ABC"}'

3.1 编码格式

json.dumps的ensure_ascii参数用来控制生成的JSON字符串的编码. 其默认值为True, 此时, 所有的非ASCII码字条都会转义. 如果不希望自动进行转义, 则会保持原有编码, 限UTF-8. 如下例所示:

>>> json.dumps({'数字': 123, '字符': '一二三'})
'{"\\u6570\\u5b57": 123, "\\u5b57\\u7b26": "\\u4e00\\u4e8c\\u4e09"}'
>>> json.dumps({'数字': 123, '字符': '一二三'}, ensure_ascii=False)
'{"数字": 123, "字符": "一二三"}'

3.2 数据类型转换

在默认实现中, json.dumps可以处理的Python对象, 及其所有的属性值, 类型必须为dict, list, tuple, str, float或者int. 这些类型与JSON的数据转换关系如下表:

Python JSON
dict object
list, tuple array
str string
int, float, int-&float-derived emuns number
True true
False false
None null

实际转换情况如下示例:

>>> json.dumps(
... {
... 'str': 'ABC',
... 'int': 123,
... 'float': 321.45,
... 'bool_true': True,
... 'bool_false': False,
... 'none': None,
... 'list': [1, 2, 3],
... 'tuple': [12, 34]
... }
... )
'{"str": "ABC", "int": 123, "float": 321.45, "bool_true": true, "bool_flase": false, "none": null, "list": [1, 2, 3], "tuple": [12, 34]}'

虽然JSON标准规范不支持NaN, Infinity和-Infinity, 但是json.dumps的默认实现会将float('nan'), float('inf')和float('-inf')转换为常量NaN, Infinity, 和-Infinity. 如下例所示:

>>> json.dumps(
... {
... 'nan': float('nan'),
... 'inf': float('inf'),
... '-inf': float('-inf')
... }
... )
'{"nan": NaN, "inf": Infinity, "-inf": -Infinity}'

由于这些常量可能会导致生成的JSON字符串不能被其他的JSON实现处理, 为了防止这种情况出现, 可以将json.dumps的allow_nan参数设置为True. 此时, 当处理的Python对象中出现这些值时, json.dumps方法会抛出异常.

3.3 循环引用

json.dumps方法会检查Python对象中是否有循环引用, 如果发现了循环引用, 就会抛出异常. 如下例所示:

>>> circular_obj = {}
>>> circular_obj['self'] = circular_obj
>>> circular_obj
{'self': {...}}
>>> json.dumps(circular_obj)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
ValueError: Circular reference detected

如果不希望json.dumps方法检查循环引用, 可以将参数check_circular设置为False. 但如果此时Python对象中有循环引用, 有可能发生递归嵌套过深的错误或者其他错误, 这么做是比较危险的. 如下例所示:

>>> json.dumps(circular_obj, check_circular=False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 238, in dumps
**kw).encode(obj)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
RecursionError: maximum recursion depth exceeded while encoding a JSON object

3.4 JSON字符串输出格式

json.dumps方法的indent参数可以用来控制JSON字符串的换行和缩进效果.

indent参数默认值为None. 此时, JSON字符串不会有换行和缩进效果. 如下示:

>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}))
{"a": 123, "b": {"x": 321, "y": "ABC"}}

当indent为0或者负数时, JSON字符会包含换行:

>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}, indent=-1))
{
"a": 123,
"b": {
"x": 321,
"y": "ABC"
}
}
>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}, indent=0))
{
"a": 123,
"b": {
"x": 321,
"y": "ABC"
}
}

而当indent为正整数时, 除了换行, JSON还会以指定数量的空格为单位在对象层次间进行缩进:

>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}, indent=2))
{
"a": 123,
"b": {
"x": 321,
"y": "ABC"
}
}

indent还可以是str, 此时, JSON会以str内容为单位进行缩进, 比如制表符\t:

>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}, indent='\t'))
{
"a": 123,
"b": {
"x": 321,
"y": "ABC"
}
}

json.dumps的另外一个参数separators可以用来设置输出的分隔符. 这个参数的值应当是一个有两个元素的tuple. 其第一个值为成员间的分隔符, 第二个值为键值之间的分隔符. 其默认值也会随上文中的indent参数影响. 当indent为None时, separators的默认值为(', ', ': '), 即分隔符后都有一个空格. 当indent不为None时, 其默认值则为(',', ':'), 即只有键值间分隔符后会有一个空格, 而元素间分隔符则不带空格, 因为此时会有换行.

separators参数的一种可能的使用场景是希望移除所有的非必要格式字符, 以此来减小JSON字符串的大小. 此时可以将separator设置为(',', ';'), 并不设置indent参数, 或者将其显式设置为None:

>>> print(json.dumps({'a': 123, 'b': {'x': 321, 'y': 'ABC'}}, indent=None, separators=(',', ':')))
{"a":123,"b":{"x":321,"y":"ABC"}}

3.5 转换自定义Python对象

json.dumps的默认实现只能转换Dictionary类型的对象. 如果想要转换自定义对象, 需要使用default参数. 这个参数接收一个函数, 这个函数的参数是一个要转换的Python对象, 返回值是能够表示这个Python对象的Dictionary对象. default函数会从对象引用树的顶层开始, 逐层遍历整个对象引用树. 因此, 不用自己实现对象树的遍历逻辑, 只需要处理当前层次的对象. 如下例所示:

>>> class MyClass:
... def __init__(self, x, y):
... self.x = x
... self.y = y
...
>>> def my_default(o):
... if isinstance(o, MyClass):
... print('%s.y: %s' % (type(o), o.y))
... return {'x': o.x, 'y': o.y}
... print(o)
... return o
...
>>> obj = MyClass(x=MyClass(x=1, y=2), y=11)
>>> json.dumps(obj, default=my_default)
<class '__main__.MyClass'>.y: 11
<class '__main__.MyClass'>.y: 2
'{"x": {"x": 1, "y": 2}, "y": 11}'

3.6 非字符串类型键名

在Python中, 只是可哈希(hashable)的对象和数据都可以做为Dictionary对象的键, 而JSON规范中则只能使用字符串做为键名. 所以在json.dumps的实现中, 对这个规则进行了检查, 不过键名允许的范围有所扩大, str, int, float, bool和None类型的数据都可以做为键名. 不过当键名非str的情况时, 键名会转换为对应的str值. 如下例:

>>> json.dumps(
... {
... 'str': 'str',
... 123: 123,
... 321.54: 321.54,
... True: True,
... False: False,
... None: None
... }
... )
'{"str": "str", "123": 123, "321.54": 321.54, "true": true, "false": false, "null": null}'

而当出现其他类型的键名时, 默认出抛出异常:

>>> json.dumps({(1,2): 123})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 231, in dumps
return _default_encoder.encode(obj)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 199, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 257, in iterencode
return _iterencode(o, 0)
TypeError: keys must be a string

json.dumps的skipkeys参数可以改变这个行为. 当将skipkeys设置为True时, 遇到非法的键名类型, 不会抛出异常, 而是跳过这个键名:

>>> json.dumps({(1,2): 123}, skipkeys=True)
'{}'

3.7 生成JSON文件

当需要将生成的JSON数据保存到文件时, 可以使用json.dump方法. 这个方法比json.dumps多了一个参数fp, 这个参数就是用来保存JSON数据的文件对象. 比如, 下例中的代码

>>> with open('/tmp/data.json', mode='a') as jf:
... json.dump({'a': 123}, jf)
...

就会将JSON数据写入到/tmp/data.json文件里. 代码执行完后, 文件内容为

{"a": 123} 
json.dump方法也可以接受其他类文件对象:
>>> sio = io.StringIO()
>>> json.dump({'a': 123}, sio)
>>> sio.getvalue()
'{"a": 123}'

json.dump的其他参数和json.dumps的用法相同, 这里不再赘述.

4 JSON解码和编码类实现

json.loads, json.load, json.dumps和json.dump这四个方法是通过json.JSONDecoder和json.JSONEncoder这两个类来完成各自的任务的. 所以也可以直接使用这两个类来完成前文描述的功能:

>>> json.JSONDecoder().decode('{"a": 123}')
{'a': 123}
>>> json.JSONEncoder().encode({'a': 123})
'{"a": 123}'

json.loads, json.load, json.dumps和json.dump这个四个方法的参数主要都是传递给了json.JSONDecoder和json.JSONEncoder的构造方法, 所以使用这些方法可以满足绝大部分需求. 当需要自定义json.JSONDecoder和json.JSONEncoder子类的时候, 只需要将子类传递给cls参数. 同时, 这些方法都有**kw参数. 当自定义实现类的构造函数需要标准参数列表之外的新参数时, 这个参数就会将新参数传递给实现类的构造方法.

5 相关资源

  1. JSON
  2. The JavaScript Object Notation (JSON) Data Interchange Format - RFC 4627
  3. json — JSON encoder and decoder

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python使用Flask框架获取当前查询参数的方法
Mar 21 Python
python文件的md5加密方法
Apr 06 Python
Python中运算符&quot;==&quot;和&quot;is&quot;的详解
Oct 08 Python
python调用OpenCV实现人脸识别功能
May 25 Python
对Python闭包与延迟绑定的方法详解
Jan 07 Python
python 处理数字,把大于上限的数字置零实现方法
Jan 28 Python
调试Django时打印SQL语句的日志代码实例
Sep 12 Python
python pygame实现挡板弹球游戏
Nov 25 Python
python GUI库图形界面开发之PyQt5滚动条控件QScrollBar详细使用方法与实例
Mar 06 Python
Python实现的北京积分落户数据分析示例
Mar 27 Python
Django如何继承AbstractUser扩展字段
Nov 27 Python
pyspark对Mysql数据库进行读写的实现
Dec 30 Python
Python 编码规范(Google Python Style Guide)
May 05 #Python
python 编码规范整理
May 05 #Python
PYTHON基础-时间日期处理小结
May 05 #Python
python 日期操作类代码
May 05 #Python
Python批量发送post请求的实现代码
May 05 #Python
PyQt5 pyqt多线程操作入门
May 05 #Python
详解pyqt5 动画在QThread线程中无法运行问题
May 05 #Python
You might like
php学习笔记 [预定义数组(超全局数组)]
2011/06/09 PHP
url decode problem 解决方法
2011/12/26 PHP
深入理解PHP之源码目录结构与功能说明
2016/06/01 PHP
PHP中的密码加密的解决方案总结
2016/10/26 PHP
Yii2框架中日志的使用方法分析
2017/05/22 PHP
PHP实现的分页类定义与用法示例
2017/07/05 PHP
swoole锁的机制代码实例讲解
2021/03/04 PHP
调试Node.JS的辅助工具(NodeWatcher)
2012/01/04 Javascript
jQuery 取值、赋值的基本方法整理
2014/03/31 Javascript
jquery插件之定时查询待处理任务数量
2014/05/01 Javascript
Nodejs全局安装和本地安装的不同之处
2016/07/04 NodeJs
非常优秀的JS图片轮播插件Swiper的用法
2017/01/03 Javascript
jQuery实现的省市联动菜单功能示例【测试可用】
2017/01/13 Javascript
PHP实现本地图片上传和验证功能
2017/02/27 Javascript
详解vue移动端项目的适配(以mint-ui为例)
2018/08/17 Javascript
vue 界面刷新数据被清除 localStorage的使用详解
2018/09/16 Javascript
用Python实现服务器中只重载被修改的进程的方法
2015/04/30 Python
Python对文件操作知识汇总
2016/05/15 Python
Python实现对字符串的加密解密方法示例
2017/04/29 Python
Python编程实现的简单神经网络算法示例
2018/01/26 Python
使用PyInstaller将python转成可执行文件exe笔记
2018/05/26 Python
pandas 对series和dataframe进行排序的实例
2018/06/09 Python
解决win64 Python下安装PIL出错问题(图解)
2018/09/03 Python
python 中的列表生成式、生成器表达式、模块导入
2019/06/19 Python
python3.6编写的单元测试示例
2019/08/17 Python
python线程安全及多进程多线程实现方法详解
2019/09/27 Python
pytorch中的transforms模块实例详解
2019/12/31 Python
Selenium结合BeautifulSoup4编写简单的python爬虫
2020/11/06 Python
安装不同版本的tensorflow与models方法实现
2021/02/20 Python
浏览器实现移动端高性能css3动画(开启gpu加速)
2013/12/23 HTML / CSS
HTML5 通过Vedio标签实现视频循环播放的示例代码
2020/08/05 HTML / CSS
智利最大的网上商店:Linio智利
2016/11/24 全球购物
现代家居用品及礼品:LBC Modern
2018/06/24 全球购物
PHP中如何使用Cookie
2015/10/28 面试题
关于国庆节的广播稿
2015/08/19 职场文书
智慧人生:永远不需要向任何人解释你自己
2019/08/20 职场文书