一、前言
1. 现实需求
每种编程语言都有各自的数据类型,其中面向对象的编程语言还允许开发者自定义数据类型(如:自定义类),Python也是一样。很多时候我们会有这样的需求:
2.数据格式
如果要将一个系统内的数据通过网络传输给其它系统或客户端,我们通常都需要先把这些数据转化为字符串或字节串,而且需要规定一种统一的数据格式才能让数据接收端正确解析并理解这些数据的含义。XML 是早期被广泛使用的数据交换格式,在早期的系统集成论文中经常可以看到它的身影;如今大家使用更多的数据交换格式是JSON(JavaScript Object Notation),它是一种轻量级的数据交换格式。JSON相对于XML而言,更加加单、易于阅读和编写,同时也易于机器解析和生成。除此之外,我们也可以自定义内部使用的数据交换格式。
如果是想把数据持久化到本地磁盘,这部分数据通常只是供系统内部使用,因此数据转换协议以及转换后的数据格式也就不要求是标准、统一的,只要本系统内部能够正确识别即可。但是,系统内部的转换协议通常会随着编程语言版本的升级而发生变化(改进算法、提高效率),因此通常会涉及转换协议与编程语言的版本兼容问题,下面要时候的pickle协议就是这样一个例子。
3. 序列化/反序列化
将对象转换为可通过网络传输或可以存储到本地磁盘的数据格式(如:XML、JSON或特定格式的字节串)的过程称为序列化;反之,则称为反序列化。
4.相关模块
本节要介绍的就是Python内置的几个用于进行数据序列化的模块:
模块名称 描述 提供的api
json 用于实现Python数据类型与通用(json)字符串之间的转换 dumps()、dump()、loads()、load()
pickle 用于实现Python数据类型与Python特定二进制格式之间的转换 dumps()、dump()、loads()、load()
shelve 专门用于将Python数据类型的持久化到磁盘,shelf是一个类似dict的对象,操作十分便捷 open()
二、json模块
大部分编程语言都会提供处理json数据的接口,Python 2.6开始加入了json模块,且把它作为一个内置模块提供,无需下载即可使用。
1. 序列化与反序列化
Python的JSON模块 序列化与反序列化的过程分别叫做:encoding 和 decoding。
json模块提供了以下两个方法来进行序列化和反序列化操作:
# 序列化:将Python对象转换成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)
# 反序列化:将json字符串转换成Python对象
loads(s, encoding=None, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
除此之外,json模块还提供了两个额外的方法允许我们直接将序列化后得到的json数据保存到文件中,以及直接读取文件中的json数据进行反序列化操作:
# 序列化:将Python对象转换成json字符串并存储到文件中
dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, cls=None, indent=None, indent=None, separators=None, default=None, sort_keys=False, **kw)
# 反序列化:读取指定文件中的json字符串并转换成Python对象
load(fp, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
2. JSON与Python之间数据类型对应关系
Python转JSON
Python JSON
dict Object
list, tuple array
str string
int, float, int- & float-derived Enums numbers
True true
False false
None null
JSON转Python
JSON Python
object dict
array list
string str
number(int) int
number(real) float
true True
false False
null None
说明:
3. 实例:内置数据类型序列化/反序列化
序列化
# 序列化
>>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)})
'{"a": "str", "c": true, "b": 11.1, "e": 10, "d": null, "g": [4, 5, 6], "f": [1, 2, 3]}'
sort_keys参数: 表示序列化时是否对dict的key进行排序(dict默认是无序的)
# 序列化并对key进行排序
>>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}, sort_keys=True)
'{"a": "str", "b": 11.1, "c": true, "d": null, "e": 10, "f": [1, 2, 3], "g": [4, 5, 6]}'
indent参数: 表示缩进的意思,它可以使得数据存储的格式变得更加优雅、可读性更强;如果indent是一个非负整数或字符串,则JSON array元素和object成员将会被以相应的缩进级别进行打印输出;如果indent是0或负数或空字符串,则将只会插入换行,不会有缩进。
# 序列化并对key进行排序及格式化输出
>>> print(json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}, sort_keys=True, indent=4))
{
"a": "str",
"b": 11.1,
"c": true,
"d": null,
"e": 10,
"f": [
1,
2,
3
],
"g": [
4,
5,
6
]
}
separators参数: 尽管indent参数可以使得数据存储的格式变得更加优雅、可读性更强,但是那是通过添加一些冗余的空白字符进行填充的。当json被用于网络数据通信时,应该尽可能的减少无用的数据传输,这样可以节省贷款并加快数据传输速度。json模块序列化Python对象后得到的json字符串中的','号和':'号分隔符后默认都会附加一个空白字符,我们可以通过separators参数重新指定分隔符,从而去除无用的空白字符;
>>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)})
'{"a": "str", "c": true, "b": 11.1, "e": 10, "d": null, "g": [4, 5, 6], "f": [1, 2, 3]}'
>>> json.dumps({'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}, separators=(',',':'))
'{"a":"str","c":true,"b":11.1,"e":10,"d":null,"g":[4,5,6],"f":[1,2,3]}'
反序列化
# 反序列化
>>> json.loads('{"a": "str", "c": true, "b": 11.1, "e": 10, "d": null, "g": [4, 5, 6], "f": [1, 2, 3]}')
{'c': True, 'e': 10, 'a': 'str', 'g': [4, 5, 6], 'd': None, 'f': [1, 2, 3], 'b': 11.1}
>>> json.loads('{"a":"str","c":true,"b":11.1,"e":10,"d":null,"g":[4,5,6],"f":[1,2,3]}')
{'c': True, 'e': 10, 'a': 'str', 'g': [4, 5, 6], 'd': None, 'f': [1, 2, 3], 'b': 11.1}
dump()与load()函数示例
# 序列化到文件中
>>> with open('test.json', 'w') as fp:
... json.dump({'a':'str中国', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}, fp, indent=4)
# 反序列化文件中的内容
>>> with open('test.json', 'r') as fp:
... json.load(fp)
{'e': 10, 'g': [4, 5, 6], 'b': 11.1, 'c': True, 'd': None, 'a': 'str中国', 'f': [1, 2, 3]}
需要说明的是: 如果试图使用相同的fp重复调用dump()函数去序列化多个对象(或序列化同一个对象多次),将会产生一个无效的JSON文件,也就是说对于一个fp只能调用一次dump()。
4. 实例:自定义数据类型的序列化/反序列化
Python是面向对象的编程语言,我们可以自定义需要的数据类型;实际工作中,我们常常会用到自定义数据类型的序列化与反序列化操作。要实现自定义数据类型的序列化与反序列化有两种方式:
首先来自定义一个数据类型
class Student(object):
def __init__(self, name, age, sno):
self.name = name
self.age = age
self.sno = sno
def __repr__(self):
return 'Student [name: %s, age: %d, sno: %d]' % (self.name, self.age, self.sno)
直接调用dumps()方法会引发TypeError错误:
>>> stu = Student('Tom', 19, 1)
>>> print(stu)
Student [name: Tom, age: 19, sno: 1]
>>>
>>> json.dumps(stu)
...
TypeError: Student [name: Tom, age: 19, sno: 1] is not JSON serializable
上面的异常信息中指出:stu对象不可以被序列化为JSON个数的数据。那么我们分别通过"编写转换函数" 和 "继承JSONEncoder和JSONDecoder类" 来实现对这个自定义数据类型的JSON序列化和反序列化。
方法1:编写转换函数
那么这个转换函数要完成哪两个数据类型之间的转换呢? 从上面列出的JSON与Python数据类型的对应表中可知,JSON中的object对应的是Python中的dict,因此要对Python中的自定义数据类型的对象进行序列化,就需要先把这个对象转换成json模块可以直接进行序列化dict类型。由此可知,这个转换函数是要完成的是Python对象(不是JSON对象)与dict之间的相互转换,且序列化时转换过程是"Python对象 --> dict --> JSON object",反序列化的过程是"JSON object -> dict --> Python对象"。所以,我们需要编写两个转换函数来分别实现序列化和反序列化时的转换过程。
def obj2dict(obj):
d = {}
d['__class__'] = obj.__class__.__name__
d['__module__'] = obj.__module__
d.update(obj.__dict__)
return d
def dict2obj(d):
if '__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
module = __import__(module_name)
class_ = getattr(module, class_name)
args = dict((key.encode('ascii'), value) for key, value in d.items())
instance = class_(**args)
else:
instance = d
return instance
继承JSONEncoder实现反序列化时还有一个额外的作用,就是可以通过iterencode()方法把一个很大的数据对象分多次进行序列化,这对于网络传输、磁盘持久化等情景非常有用。
>>> for chunk in MyJSONEncoder().iterencode(stu):
... print(chunk)
...
{
"__class__"
:
"Student"
,
"name"
:
"Tom"
,
"__module__"
:
"__main__"
,
"sno"
:
1
,
"age"
:
19
}
大数据对象序列化网络传输伪代码:
for chunk in JSONEncoder().iterencode(bigobject):
mysocket.write(chunk)
序列化测试:
>>> import json
>>> obj2dict(stu)
{'sno': 1, '__module__': '__main__', 'age': 19, '__class__': 'Student', 'name': 'Tom'}
>>> json.dumps(obj2dict(stu))
'{"sno": 1, "__module__": "__main__", "age": 19, "__class__": "Student", "name": "Tom"}'
>>> json.dumps(stu, default=obj2dict)
'{"sno": 1, "__module__": "__main__", "age": 19, "__class__": "Student", "name": "Tom"}'
json.dumps(stu, default=obj2dict)
等价于json.dumps(obj2dict(stu))
反序列化测试:
>>> json.loads('{"sno": 1, "__module__": "__main__", "age": 19, "__class__": "Student", "name": "Tom"}')
{u'sno': 1, u'__module__': u'__main__', u'age': 19, u'name': u'Tom', u'__class__': u'Student'}
>>> dict2obj(json.loads('{"sno": 1, "__module__": "__main__", "age": 19, "__class__": "Student", "name": "Tom"}'))
Student [name: Tom, age: 19, sno: 1]
>>> json.loads('{"sno": 1, "__module__": "__main__", "age": 19, "__class__": "Student", "name": "Tom"}', object_hook=dict2obj)
Student [name: Tom, age: 19, sno: 1]
json.loads(JSON_STR, object_hook=dict2obj)
等价于 dict2obj(json.loads(JSON_STR))
方法2:继承JSONEncoder和JSONDecoder实现子类
import json
class MyJSONEncoder(json.JSONEncoder):
def default(self, obj):
d = {}
d['__class__'] = obj.__class__.__name__
d['__module__'] = obj.__module__
d.update(obj.__dict__)
return d
class MyJSONDecoder(json.JSONDecoder):
def __init__(self):
json.JSONDecoder.__init__(self, object_hook=self.dict2obj)
def dict2obj(self, d):
if '__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
module = __import__(module_name)
class_ = getattr(module, class_name)
args = dict((key.encode('ascii'), value) for key, value in d.items())
instance = class_(**args)
else:
instance = d
return instance
序列化测试:
>>> stu = Student('Tom', 19, 1)
# 方式一:直接调用子类MyJSONEncoder的encode()方法进行序列化
>>> MyJSONEncoder().encode(stu)
'{"__class__": "Student", "__module__": "__main__", "name": "Tom", "age": 19, "sno": 1}'
>>> MyJSONEncoder(separators=(',', ':')).encode(stu)
'{"__class__":"Student","__module__":"__main__","name":"Tom","age":19,"sno":1}'
# 方式二:将子类MyJSONEncoder作为cls参数的值传递给json.dumps()函数
>>> json.dumps(stu, cls=MyJSONEncoder)
'{"__class__": "Student", "__module__": "__main__", "name": "Tom", "age": 19, "sno": 1}'
>>> json.dumps(stu, cls=MyJSONEncoder, separators=(',', ':'))
'{"__class__":"Student","__module__":"__main__","name":"Tom","age":19,"sno":1}'
反序列化测试:
>>> MyJSONDecoder().decode('{"sno": 1, "__module__": "__main__", "age": 19, "__class__": "Student", "name": "Tom"}')
Student [name: Tom, age: 19, sno: 1]
说明: 经过测试发现MyJSONDecoder().decode(JSON_STR)
和json.loads(JSON_STR, object_hook=dict2obj)
只能在Python 2.7上正确执行,在Python 3.5上无法正确执行;而json.loads(JSON_STR, cls=MyJSONDecoder)
无论在Python 2.7还是在Python 3.5上都无法正确执行。这说明json模块对于自定义数据类型的反序列化支持还是比较有限的,但是我们也可以通过json.loads(JSON_STR)函数,不指定cls参数来得到一个dict对象,然后自己完成dict到object的转换。
三、pickle模块
pickle模块实现了用于对Python对象结构进行 序列化 和 反序列化 的二进制协议,与json模块不同的是pickle模块序列化和反序列化的过程分别叫做 pickling 和 unpickling:
1. pickle模块与json模块对比
2. pickle模块使用的数据流格式
上面提到,pickle使用的数据格式是特定于Python的。这使得它不受诸如JSON或XDR的外部标准限值,但是这也意味着非Python程序可能无法重建pickled Python对象。默认情况下,pickle数据格式使用相对紧凑的二进制表示。如果需要最佳大小特征,可以有效的压缩pickled数据。pickletools模块包含可以用于对pickle生成的数据流进行分析的工具。目前有5种不同的协议可以用于pickle。使用的协议越高,就需要更新的Python版本去读取pickle产生的数据:
说明: Python 2.x中默认使用的是协议v0,如果协议指定为赋值或HIGHEST_PROTOCOL,将使用当前可用的最高协议版本;Python 3.x中默认使用的是协议v3,它兼容其他Python 3版本,但是不兼容Python 2。
注意: 序列化(Serialization)是一个比持久化(Persistence)更加原始的概念;虽然pickle
可以读写文件对象,但是它不处理持久化对象的命名问题,也不处理对持久化对象的并发访问问题(甚至更复杂的问题)。pickle
模块可以将复杂对象转换为字节流,并且可以将字节流转换为具有相同内部结构的对象。或许最可能对这些字节流做的事情是将它们写入文件,但是也可以对它们进行网络传输或将它们存储在数据库中。shelve
模块提供了一个简单的接口用于在DBM风格的数据库文件上对对象进行pickle和unpickle操作。
3. pickle模块提供的相关函数
pickle模块提供的几个序列化/反序列化的函数与json模块基本一致:
# 将指定的Python对象通过pickle序列化作为bytes对象返回,而不是将其写入文件
dumps(obj, protocol=None, *, fix_imports=True)
# 将通过pickle序列化后得到的字节对象进行反序列化,转换为Python对象并返回
loads(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict")
# 将指定的Python对象通过pickle序列化后写入打开的文件对象中,等价于`Pickler(file, protocol).dump(obj)`
dump(obj, file, protocol=None, *, fix_imports=True)
# 从打开的文件对象中读取pickled对象表现形式并返回通过pickle反序列化后得到的Python对象
load(file, *, fix_imports=True, encoding="ASCII", errors="strict")
说明: 上面这几个方法参数中,*号后面的参数都是Python 3.x新增的,目的是为了兼容Python 2.x,具体用法请参看官方文档。
4. 实例:内置数据类型的序列化/反序列化
Python 2.x
>>> import pickle
>>>
>>> var_a = {'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}
# 序列化
>>> var_b = pickle.dumps(var_a)
>>> var_b
"(dp0\nS'a'\np1\nS'str'\np2\nsS'c'\np3\nI01\nsS'b'\np4\nF11.1\nsS'e'\np5\nI10\nsS'd'\np6\nNsS'g'\np7\n(I4\nI5\nI6\ntp8\nsS'f'\np9\n(lp10\nI1\naI2\naI3\nas."
# 反序列化
>>> var_c = pickle.loads(var_b)
>>> var_c
{'a': 'str', 'c': True, 'b': 11.1, 'e': 10, 'd': None, 'g': (4, 5, 6), 'f': [1, 2, 3]}
Python 3.x
>>> import pickle
>>>
>>> var_a = {'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}
# 序列化
>>> var_b = pickle.dumps(var_a)
>>> var_b
b'\x80\x03}q\x00(X\x01\x00\x00\x00eq\x01K\nX\x01\x00\x00\x00aq\x02X\x03\x00\x00\x00strq\x03X\x01\x00\x00\x00fq\x04]q\x05(K\x01K\x02K\x03eX\x01\x00\x00\x00gq\x06K\x04K\x05K\x06\x87q\x07X\x01\x00\x00\x00bq\x08G@&333333X\x01\x00\x00\x00cq\t\x88X\x01\x00\x00\x00dq\nNu.'
# 反序列化
>>> var_c = pickle.loads(var_b)
>>> var_c
{'e': 10, 'a': 'str', 'f': [1, 2, 3], 'g': (4, 5, 6), 'b': 11.1, 'c': True, 'd': None}
dump()与load()
>>> import pickle
>>>
>>> var_a = {'a':'str', 'c': True, 'e': 10, 'b': 11.1, 'd': None, 'f': [1, 2, 3], 'g':(4, 5, 6)}
# 持久化到文件
>>> with open('pickle.txt', 'wb') as f:
... pickle.dump(var_a, f)
...
# 从文件中读取数据
>>> with open('pickle.txt', 'rb') as f:
... var_b = pickle.load(f)
...
>>> var_b
{'e': 10, 'a': 'str', 'f': [1, 2, 3], 'g': (4, 5, 6), 'b': 11.1, 'c': True, 'd': None}
>>>
说明:
5. 实例:自定义数据类型的序列化/反序列化
首先来自定义一个数据类型:
class Student(object):
def __init__(self, name, age, sno):
self.name = name
self.age = age
self.sno = sno
def __repr__(self):
return 'Student [name: %s, age: %d, sno: %d]' % (self.name, self.age, self.sno)
pickle模块可以直接对自定数据类型进行序列化/反序列化操作,无需编写额外的处理函数或类。
>>> stu = Student('Tom', 19, 1)
>>> print(stu)
Student [name: Tom, age: 19, sno: 1]
# 序列化
>>> var_b = pickle.dumps(stu)
>>> var_b
b'\x80\x03c__main__\nStudent\nq\x00)\x81q\x01}q\x02(X\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Tomq\x04X\x03\x00\x00\x00ageq\x05K\x13X\x03\x00\x00\x00snoq\x06K\x01ub.'
# 反序列化
>>> var_c = pickle.loads(var_b)
>>> var_c
Student [name: Tom, age: 19, sno: 1]
# 持久化到文件
>>> with open('pickle.txt', 'wb') as f:
... pickle.dump(stu, f)
...
# 从文件总读取数据
>>> with open('pickle.txt', 'rb') as f:
... pickle.load(f)
...
Student [name: Tom, age: 19, sno: 1]
四、shelve模块
shelve是一个简单的数据存储方案,类似key-value数据库,可以很方便的保存python对象,其内部是通过pickle协议来实现数据序列化。shelve只有一个open()函数,这个函数用于打开指定的文件(一个持久的字典),然后返回一个shelf对象。shelf是一种持久的、类似字典的对象。它与"dbm"的不同之处在于,其values值可以是任意基本Python对象--pickle模块可以处理的任何数据。这包括大多数类实例、递归数据类型和包含很多共享子对象的对象。keys还是普通的字符串。
open(filename, flag='c', protocol=None, writeback=False)
flag 参数表示打开数据存储文件的格式,可取值与dbm.open()
函数一致:
值 描述
'r' 以只读模式打开一个已经存在的数据存储文件
'w' 以读写模式打开一个已经存在的数据存储文件
'c' 以读写模式打开一个数据存储文件,如果不存在则创建
'n' 总是创建一个新的、空数据存储文件,并以读写模式打开
protocol 参数表示序列化数据所使用的协议版本,默认是pickle v3;
writeback 参数表示是否开启回写功能。
我们可以把shelf对象当dict来使用--存储、更改、查询某个key对应的数据,当操作完成之后,调用shelf对象的close()函数即可。当然,也可以使用上下文管理器(with语句),避免每次都要手动调用close()方法。
实例:内置数据类型操作
# 保存数据
with shelve.open('student') as db:
db['name'] = 'Tom'
db['age'] = 19
db['hobby'] = ['篮球', '看电影', '弹吉他']
db['other_info'] = {'sno': 1, 'addr': 'xxxx'}
# 读取数据
with shelve.open('student') as db:
for key,value in db.items():
print(key, ': ', value)
输出结果:
name : Tom
age : 19
hobby : ['篮球', '看电影', '弹吉他']
other_info : {'sno': 1, 'addr': 'xxxx'}
实例:自定义数据类型操作
# 自定义class
class Student(object):
def __init__(self, name, age, sno):
self.name = name
self.age = age
self.sno = sno
def __repr__(self):
return 'Student [name: %s, age: %d, sno: %d]' % (self.name, self.age, self.sno)
# 保存数据
tom = Student('Tom', 19, 1)
jerry = Student('Jerry', 17, 2)
with shelve.open("stu.db") as db:
db['Tom'] = tom
db['Jerry'] = jerry
# 读取数据
with shelve.open("stu.db") as db:
print(db['Tom'])
print(db['Jerry'])
输出结果:
Student [name: Tom, age: 19, sno: 1]
Student [name: Jerry, age: 17, sno: 2]
五、总结
1. 对比
json模块常用于编写web接口,将Python数据转换为通用的json格式传递给其它系统或客户端;也可以用于将Python数据保存到本地文件中,缺点是明文保存,保密性差。另外,如果需要保存费内置数据类型需要编写额外的转换函数或自定义类。
pickle模块和shelve模块由于使用其特有的序列化协议,其序列化之后的数据只能被Python识别,因此只能用于Python系统内部。另外,Python 2.x 和 Python
3.x 默认使用的序列化协议也不同,如果需要互相兼容需要在序列化时通过protocol参数指定协议版本。除了上面这些缺点外,pickle模块和shelve模块相对于json模块的优点在于对于自定义数据类型可以直接序列化和反序列化,不需要编写额外的转换函数或类。
shelve模块可以看做是pickle模块的升级版,因为shelve使用的就是pickle的序列化协议,但是shelve比pickle提供的操作方式更加简单、方便。shelve模块相对于其它两个模块在将Python数据持久化到本地磁盘时有一个很明显的优点就是,它允许我们可以像操作dict一样操作被序列化的数据,而不必一次性的保存或读取所有数据。
2. 建议
3. 附录
要实现的功能 可以使用的api
将Python数据类型转换为(json)字符串 json.dumps()
将json字符串转换为Python数据类型 json.loads()
将Python数据类型以json形式保存到本地磁盘 json.dump()
将本地磁盘文件中的json数据转换为Python数据类型 json.load()
将Python数据类型转换为Python特定的二进制格式 pickle.dumps()
将Python特定的的二进制格式数据转换为Python数据类型 pickle.loads()
将Python数据类型以Python特定的二进制格式保存到本地磁盘 pickle.dump()
将本地磁盘文件中的Python特定的二进制格式数据转换为Python数据类型 pickle.load()
以类型dict的形式将Python数据类型保存到本地磁盘或读取本地磁盘数据并转换为数据类型 shelve.open()
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。