??xml version="1.0" encoding="utf-8" standalone="yes"?>
2 # -*- coding: utf-8 -*-
3
4 '''
5 gcc2vs.py
6
7 功能Q?br /> 8 剪切板中gcc的编译输出格式{成vs格式Q用于vs跌{到错误行?br /> 9 vs2017 linux ~译输出?nbsp;gcc 格式Q无法点击蟩转,如:
10 /var/tmp/src/dbe/Linux-Debug/Src/Team.cpp:16:1: 错误Q?#8216;x’不是一个类型名
11 {为vs格式, ?br />12 /var/tmp/src/dbe/Linux-Debug/Src/Team.cpp(16):1: 错误Q?#8216;x’不是一个类型名
13
14 如何使用Q?br />15
16 首先d?nbsp;python, q安?nbsp;pyperclip
17 pip install pyperclip
18
19 假设本文件ؓ d:/tools/gcc2vs.py,
20 vs讄外部工具Q工?>外部工具->d
21 标题Qgcc2vs(&V)
22 命oQpython.exe
23 参数Qd:/tools/gcc2vs.py
24 选中"使用输出H口"
25
26 参考:VS2010手动d外部工具和快捷键
27 https://www.cnblogs.com/ChinaHook/p/4698733.html
28
29 当Linux构徏输出后,点击输出H口Qctrl-A 选择全部Qctrl-C 复制输出到剪切板Q?br />30 然后 alt-T,V q行d的外部工?nbsp;gcc2vs(&V), 更改输出格式Q然后就可以点击错误跌{了?br />31 '''
32
33 import re
34 import pyperclip
35
36 # 待替换的格式
37 pattern = re.compile(r'/var/tmp/src/..-
.-
.-
.-
/Linux-Debug/(.*):([0-9]*):([0-9]*): ')
38
39 test_lines_src = '''
40 /var/tmp/src/db71a8ec-90bb-2838-98df-2dd35e71166e/Linux-Debug/003_servers/103_LobbyServer/Src/Team.cpp:16:1: 错误Q?#8216;x’不是一个类型名
41 生成p|?br />42 '''
43 test_lines_dst = '''
44 003_servers/103_LobbyServer/Src/Team.cpp(16):1: 错误Q?#8216;x’不是一个类型名
45 生成p|?br />46 '''
47 assert test_lines_dst == re.sub(pattern, r'\1(\2):\3: ', test_lines_src)
48
49 # 剪切板中的gcc格式输出
50 src = pyperclip.paste()
51 # 转成vs格式
52 dst = re.sub(pattern, r'\1(\2):\3: ', src)
53 print(dst)
54
]]>
(金庆的专?
{划的配|表?xlsx 表格Q可以有注释Q公式?br />服务器和客户端用的配置文g需要{?csv 文g?br />使用 WPS 另存无法扚w转换Qƈ且结果不是utf8~码的,q需要用Notepad++转编码?br />
除了 xlsx 转ؓ csv, 其他格式文g保持原样Q如 *.ini, *.xml, *.lua.
server/ 子目录特D处理,不能复制到客L?br />
用python脚本实现Q依?openpyxl 库?br />
#!/usr/bin/env python
# coding: utf-8
# datatab.py
# 从策划配|表目录 game\Design\配置表\”
# 生成服务器的 game\Program\server\six\datatab\” 目录Q?br /># 和客L?game\Program\client\Assets\Config\” 目录?br /># 所有xlsx文g生成csv文gQ其他文件原样复制?br /># 其中 server\ 目录Ҏ处理Q仅Ҏ务器有效Q客L跌?
#
# 依赖openpyxl库:http://openpyxl.readthedocs.org/en/latest/
# 参考代?http://segmentfault.com/q/1010000003006437?_ea=273128
# 试环境QPython3.4
# Usage: datatab.py <game dir>
# Example: datatab.py "d:\game"
# <game dir> 是根目录Q包含Design/, Program/ 目录?br />
from openpyxl import Workbook
from openpyxl.compat import range
from openpyxl.cell import get_column_letter
from openpyxl import load_workbook
import csv
import os
import sys
import shutil
def xlsx2csv(filename):
# try:
xlsx_file_reader = load_workbook(filename = filename, data_only = True)
for sheet in xlsx_file_reader.get_sheet_names():
# 仅第1个sheet输出C个csv文g中,文g名后~替换?csv
csv_filename = os.path.splitext(filename)[0] + '.csv'
csv_file = open(csv_filename, 'w', encoding='utf8', newline='')
csv_file_writer = csv.writer(csv_file)
sheet_ranges = xlsx_file_reader[sheet]
for row in sheet_ranges.rows:
row_container = []
for cell in row:
row_container.append(cell.value)
csv_file_writer.writerow(row_container)
# End of for row.
csv_file.close()
break # 仅输出第1个sheet
# End of for sheet.
# End of try.
# except Exception as e:
# print(e)
# End of xlsx2csv().
def datatab_convert(game_dir):
'''?game\Design\配置表\ 输出?br /> game\Program\server\six\datatab\
game\Program\client\Assets\Config\
'''
design_dir = os.path.join(game_dir, 'Design/配置?')
server_dir = os.path.join(game_dir, 'Program/server/six/datatab/')
client_dir = os.path.join(game_dir, 'Program/client/Assets/Config/')
# 删除旧文件?br /> print("Delete " + server_dir)
try:
shutil.rmtree(server_dir)
except:
pass
print("Delete " + client_dir)
try:
shutil.rmtree(client_dir)
except:
pass
# 生成server文g
print("Creating " + server_dir)
shutil.copytree(design_dir, server_dir)
files = get_files(server_dir)
convert_files(files)
# 复制client文g
print("Copy " + client_dir)
shutil.copytree(server_dir, client_dir)
shutil.rmtree(os.path.join(client_dir, 'server/'))
print("Done. Total files: %d" % len(files))
# End of datatab_convert().
def get_files(dir):
'''Get a list of files under input dir.'''
result = []
for root,dirs,files in os.walk(dir):
for f in files:
result.append(os.path.join(root, f))
return result
# End of get_files().
def convert_files(files):
'''转换一Ҏ?
files 是列表,元素为完整\径名?br /> '''
for f in files:
ext = os.path.splitext(f)[1].lower()
if '.xlsx' != ext:
print(f + " -> keep")
continue
print(f + " -> csv")
xlsx2csv(f)
os.remove(f)
# End of convert_files().
if __name__ == '__main__':
if len(sys.argv) != 2:
print('usage: datatab <game dir>')
else:
datatab_convert(sys.argv[1])
sys.exit(0)
# Usage: datatab.py <game dir>
# Example: datatab.py "d:\game"
# <game dir> 是SVN根目录,包含Design/, Program/ 目录?br />
为方便用,datatab.py 打包?exe, q样不能安装Pythonpq行?br />下蝲q安装Python3, 安装openpyxl包,保证本地可以q行 datatab.py.
下蝲q安装PyInstallerQ?br /> pip install pyinstaller
q行
pyinstaller --onefile datatab.py
ImportError: No module named 'jdcal'
可能openpyxl安装时自带的jdcal无法扑ֈQ删?
C:\Python34\Lib\site-packages\jdcal-1.0-py3.4.egg
重新安装Qpip install jdcal
]]>
假设protobuf-py已经按照protobuf的安装说明安装了?br />发现 protobuf-2.5.0版的python包是python2的,没有扑ֈpython3的?br />试着2to3.py转换一下,l果转换后无法安装?br />只好python3.3换成python2.7
python2.7的mimetypes.py有错误,注册表中HKEY_CLASSES_ROOT有中文的扩展名时Q?br />安装setuptoolsp|Q参?http://www.oschina.net/question/1409342_134600
先编?rpz, 生成的
protoc-gen-cpp_rpcz.exe
protoc-gen-python_rpcz.exe
复制到系l搜索目录,如与protoc.exe攑֜一赗?br />
q入 rpcz ?python 目录Q运?br />python setup.py install
出现如下的各U错误:
../include\rpcz/connection_manager.hpp(21) : fatal error C1083: Cannot open incl
ude file: 'boost/function.hpp': No such file or directory
../include\rpcz/macros.hpp(20) : fatal error C1083: Cannot open include file: 'g
oogle/protobuf/stubs/common.h': No such file or directory
../include\rpcz/rpc.hpp(24) : fatal error C1083: Cannot open include file: 'rpcz
/rpcz.pb.h': No such file or directory
LINK : fatal error LNK1181: cannot open input file 'rpcz.lib'
LINK : fatal error LNK1104: cannot open file 'libboost_thread-vc100-mt-1_54.lib'
直接改了setup.py如下?br />
ext_modules=[
Extension("rpcz.pywraprpcz", ["cython/pywraprpcz.cpp"],
libraries=["rpcz", "libprotobuf", "libzmq"],
include_dirs=['../include', '../build/src',
'D:/Boost/include/boost-1_54',
'G:/workspace/rpcz_jinq/src',
'D:/LibSrc/protobuf-2.5.0/vsprojects/include'],
library_dirs=['../build/deps/lib', '../build/src/rpcz',
'D:/Boost/lib',
'G:/workspace/rpcz_jinq/src/rpcz/Release',
'D:/LibSrc/zeromq-4.0.3/builds/msvc/Release',
'D:/LibSrc/protobuf-2.5.0/vsprojects/Release'],
language='c++')
],
不知道如何做成通用的脚本?br />rpcz原来应该是徏立一个固定位|的build目录Q其中有deps目录Q包含所有库?br />q就要求cmake的构建目录固定ؓbuild.
python2.7是用VC2008~译的,用VC2010~译python扩展会有问题?br />会报错:
error: Unable to find vcvarsall.bat
强制使用VC2010:
SET VS90COMNTOOLS=%VS100COMNTOOLS%
参考:http://stackoverflow.com/questions/2817869/error-unable-to-find-vcvarsall-bat
最后进?examples\pythonQ先 generate_protos.gy 生成消息和接口,然后q行 server, client.
q行旉?libzmq.dll, rpcz.dll.
]]>
Q金庆的专栏Q?br />
一D늮单的代码Q读取stdin, 替换输出到stdout:
#!/usr/bin/env python
import os, sys
input_file = sys.stdin
output_file = sys.stdout
for s in input_file:
output_file.write(s.replace("abc", "def"))
代码改自CookBook?nbsp;
Recipe 2.3. Searching and Replacing Text in a File
在Linux上运行正常:
$ cat input.txt | ./replace.py
但是在Windows的DosH口q行会报错:
> type input.txt | replace.py
Traceback...
for s in input_file:
IOError: [Errno 9] Bad file descriptor
如果用python调用正常:
> type input.txt | python replace.py
原因是cmd.exe通过后缀兌q行py文g存在问题?br />详见QBad pipe filedescriptor when reading from stdin in python
http://stackoverflow.com/questions/1057638/bad-pipe-filedescriptor-when-reading-from-stdin-in-python
It seems that stdin/stdout redirect does not work when starting from a file association. This is not specific to python, but a problem caused by win32 cmd.exe.
]]>
Q金庆的专栏Q?br />
Flash和Unity3D游戏服务器需要开启一个Socket Policy服务器?br />详细说明见:Setting up a socket policy file server
http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html
协议如下Q?br />Flash或U3D播放器向Socket Policy服务器发送请求:
“<policy-file-request/>\0”Q?br />服务器返回一个xml文本Q其中有包含<cross-domain-policy>配置?br />
Adobe提供了Perl和Python代码。Unity3D提供了CSharp代码?br />cs代码用于Windows. Linux上准备用Python代码?br />在以上网下载:flashpolicyd_v0.6.zip?br />其中?个版本:init服务Qxinetd服务Q独立应用。只需一U即可?br />
按应用的性质Q请求量极小Q所以最适合应用xinetd.
只需q行其中的install.sh׃安装?br />q需手工?ect/services中添加服务名flashpolicy和端?43.
q行以下指o可以试一下,输出应该是配|文件的内容?br />python -c 'print "<policy-file-request/>%c" % 0' | nc 127.0.0.1 843
其实以上试指o在尾部多了个'\n', 不是标准的测试?br />在in.flashpolicyd.py中多了个strip()去除q个'\n'.
实际用U3D试Ӟ因ؓ没有'\n'l尾Q所以in.flashpolicyd.py无法正常工作?br />需要将35行readline()如下更改Q?br /> request = sys.stdin.readline().strip()
改ؓ
request = sys.stdin.readline(len('<policy-file-request/>\0')).strip()
q样׃需要eol可以读取了?br />
查看其他两个版本的代码没有这个错误,但是有另一个错误,
x可能只读一半的h造成判断出错?br />
q有一个问题是因ؓ服务是由nobodyq行的,环境变量不同Q?br />in.flashpolicyd.py头部?br />#!/usr/bin/env python
明确?br />#!/usr/local/sbin/python
可避免调用低版本的python而报错?br />
]]>
]]>
最新版本见Q?a >http://wiki.woodpecker.org.cn/moin/PP3eD
19.4. Pickled Objects
19.4. Pickle对象
Probably
the biggest limitation of DBM keyed files is in what they can store:
data stored under a key must be a simple text string. If you want to
store Python objects in a DBM file, you can sometimes manually convert
them to and from strings on writes and reads (e.g., with str and eval
calls), but this takes you only so far. For arbitrarily complex Python
objects such as class instances and nested data structures, you need
something more. Class instance objects, for example, cannot be later
re-created from their standard string representations. Custom to-string
conversions are error prone and not general.
DBM
键控文gQDBM keyed
fileQ最大的限制也许在于他们可以存储的东西:一个键g存储的数据必L个简单文本字W串。如果您惌在DBM文g中储存Python对象Q有时您
可以在读写的时候,手动q行与字W串的{换(例如Q用str和eval调用Q,但只能做到这栗对L复杂的Python对象Q如cd例和嵌套的数据结
构,您需要更多的东西。例如,cd例对象以后无法从其标准字W串表达Qstring
representationQ重建。自定义的到字符串的转换Ҏ出错Qƈ且不通用?
The
Python pickle module, a standard part of the Python system, provides
the conversion step needed. It converts nearly arbitrary Python
in-memory objects to and from a single linear string format, suitable
for storing in flat files, shipping across network sockets between
trusted sources, and so on. This conversion from object to string is
often called serializationarbitrary data structures in memory are
mapped to a serial string form.
Python
pȝ的标准部Ӟpickle模块Q提供了所需的{换步骤。它可以几乎Q意的Python内存对象Q{换ؓ单一U性的字符串格式,使之适于无格式文件存
储,或在可靠来源之间跨越|络套接口传输等{,q可反向转换。这U从对象到字W串的{换通常被称为序列化QserializationQ:内存中的Q?
数据l构映射Z行字W串形式?
The
string representation used for objects is also sometimes referred to as
a byte stream, due to its linear format. It retains all the content and
references structure of the original in-memory object. When the object
is later re-created from its byte string, it will be a new in-memory
object identical in structure and value to the original, though located
at a different memory address. The re-created object is effectively a
copy of the original.
对象的字W串表达׃其线性的格式Q有时也被称为字节流。它包含了原始内存中对象的所有内容和引用l构。当对象后来从其字节串重建时Q内存中新徏的对象与原对象具有相同的l构和|但位于不同的内存地址。该重徏对象实际上是原对象的复制?
Pickling
works on almost any Python datatypenumbers, lists, dictionaries, class
instances, nested structures, and moreand so is a general way to store
data. Because pickles contain native Python objects, there is almost no
database API to be found; the objects stored are processed with normal
Python syntax when they are later retrieved.
Pickle可用于几乎所有的Python数据cdQ数字、列表、字典、类实例、嵌套结构,{等Q因此它是存储数据的通用Ҏ。因为pickle包含的是Python本地对象Q所以几乎没有数据库的APIQ对象存储与处理及后来的提取用的都是通常的Python语法?
19.4.1. Using Object Pickling
19.4.1. 使用对象pickle
Pickling
may sound complicated the first time you encounter it, but the good
news is that Python hides all the complexity of object-to-string
conversion. In fact, the pickle module 's interfaces are incredibly
simple to use. For example, to pickle an object into a serialized
string, we can either make a pickler and call its methods or use
convenience functions in the module to achieve the same effect:
W?
一ơ听到pickleQ可能觉得有点复杂,但好消息是,Python隐藏了所有从对象到字W串转换的复杂性。事实上Qpickle模块的接口简单易用,
直o人难以置信。例如,要pickle对象C个序列化字符Ԍ我们可以生成一个picklerQƈ调用其方法,或用模块中的便捷函数来辑ֈ相同的效
果:
P = pickle.Pickler( file)
Make a new pickler for pickling to an open output file object file.
生成一个新的picklerQ用来pickleC个打开的输出文件对象file?
P.dump( object)
Write an object onto the pickler's file/stream.
写一个对象到pickler的文??
pickle.dump( object, file)
Same as the last two calls combined: pickle an object onto an open file.
{同于上两个调用的组合:pickle对象C个打开的文件?
string = pickle.dumps( object)
Return the pickled representation of object as a character string.
q回一个字W串作ؓ已pickle对象的表达?
Unpickling
from a serialized string back to the original object is similarboth
object and convenience function interfaces are available:
从一个序列化字符串unpickle回原始对象是cM的,可以用对象也可以用便捷函数接口:
U = pickle.Unpickler( file)
Make an unpickler for unpickling from an open input file object file.
生成一个unpicklerQ用来从一个打开的文件对象file unpickle?
object = U.load( )
Read an object from the unpickler's file/stream.
从unpickler的文?读取一个对象?
object = pickle.load( file)
Same as the last two calls combined: unpickle an object from an open file.
{同于上两个调用的组合:从一个打开的文件unpickle一个对象?
object = pickle.loads( string)
Read an object from a character string rather than a file.
从字W串d一个对象,而不是从文g?
Pickler
and Unpickler are exported classes. In all of the preceding cases, file
is either an open file object or any object that implements the same
attributes as file objects:
Pickler和Unpickler是导出类。在上述所有情况下Qfile是个已打开的文件对象,或者是实现了以下文件对象属性的M对象Q?
Pickler calls the file's write method with a string argument.
Pickler会调用文件的writeҎQ参数是个字W串?
Unpickler calls the file's read method with a byte count, and readline without arguments.
Unpickler会调用文件的readҎQ参数是字节敎ͼ以及readlineQ无参数?
Any
object that provides these attributes can be passed in to the file
parameters. In particular, file can be an instance of a Python class
that provides the read/write methods (i.e., the expected file-like
interface). This lets you map pickled streams to in-memory objects with
classes, for arbitrary use. For instance, the StringIO standard library
module discussed in Chapter 3 provides classes that map file calls to
and from in-memory strings.
?
何提供这些属性的对象都可以作为file参数传入。特别是Qfile可以是一个提供了?写方法的Pythoncd例(即预期的cM文g的接口)。这让您
可以用类映射pickle到内存对象Qƈ可Q意用。例如,W?章讨论的标准库模块StringIO提供的类Q它们可映射文g调用到内存字W串或反之?
This
hook also lets you ship Python objects across a network, by providing
sockets wrapped to look like files in pickle calls at the sender, and
unpickle calls at the receiver (see the sidebar "Making Sockets Look
Like Files," in Chapter 13, for more details). In fact, for some,
pickling Python objects across a trusted network serves as a simpler
alternative to network transport protocols such as SOAP and XML-RPC;
provided that Python is on both ends of the communication (pickled
objects are represented with a Python-specific format, not with XML
text).
?
挂钩也可以让您通过|络传输Python对象Q只要封装套接口Q之看上去像发送端pickle调用中的文gQ以及像接收端unpickle调用中的文g
Q详见第13章侧?#8220;使套接口看上d文g”Q。事实上Q对一些h来说Qpickle
Python对象q在一个值得信赖的网l上传输Q是替代如SOAP和XML-RPC之类|络传输协议的一个简单方法;只要通信的两端都有PythonQ被
pickle的对象是用Python专有的格式表辄Q而不是用XML文本Q?
19.4.2. Picking in Action
19.4.2. Pickle实战
In more typical use, to pickle an object to a flat file, we just open the file in write mode and call the dump function:
典型的用情冉|Qpickle对象到无格式文gQ我们只需以写模式打开文gQƈ调用dump函数Q?
% python
>>> table = {'a': [1, 2, 3],
'b': ['spam', 'eggs'],
'c': {'name':'bob'}}
>>>
>>> import pickle
>>> mydb = open('dbase', 'w')
>>> pickle.dump(table, mydb)
Notice
the nesting in the object pickled herethe pickler handles arbitrary
structures. To unpickle later in another session or program run, simply
reopen the file and call load:
注意q个被pickle对象中的嵌套Qpickler可以处理Ll构。然后,在另一个会话或E序中unpickleQ只要重新打开该文Ӟq调用loadQ?
% python
>>> import pickle
>>> mydb = open('dbase', 'r')
>>> table = pickle.load(mydb)
>>> table
{'b': ['spam', 'eggs'], 'a': [1, 2, 3], 'c': {'name': 'bob'}}
The
object you get back from unpickling has the same value and reference
structure as the original, but it is located at a different address in
memory. This is true whether the object is unpickled in the same or a
future process. In Python-speak, the unpickled object is == but is not
is:
unpickle所得的对象h与原对象相同的值和引用l构Q但它位于不同的内存地址。无论在同一q程或另一q程unpickleQ都是这栗用Python的话来说Qunpickle后的对象?#8220;==”关系Q但不是“is”关系Q?
% python
>>> import pickle
>>> f = open('temp', 'w')
>>> x = ['Hello', ('pickle', 'world')] # list with nested tuple
>>> pickle.dump(x, f)
>>> f.close( ) # close to flush changes
>>>
>>> f = open('temp', 'r')
>>> y = pickle.load(f)
>>> y
['Hello', ('pickle', 'world')]
>>>
>>> x == y, x is y
(True, False)
To
make this process simpler still, the module in Example 19-1 wraps
pickling and unpickling calls in functions that also open the files
where the serialized form of the object is stored.
Z让这一q程更简单,?9-1中的模块把pickle和unpickle调用装在函CQ在函数中同时还打开文gQƈ对象的序列化存储在该文件中?
Example 19-1. PP3E\Dbase\filepickle.py
1 import pickle
2
3 def saveDbase(filename, object):
4 file = open(filename, 'w')
5 pickle.dump(object, file) # pickle to file
6 file.close( ) # any file-like object will do
7
8 def loadDbase(filename):
9 file = open(filename, 'r')
10 object = pickle.load(file) # unpickle from file
11 file.close( ) # re-creates object in memory
12 return object
To
store and fetch now, simply call these module functions; here they are
in action managing a fairly complex structure with multiple references
to the same nested objectthe nested list called L at first is stored
only once in the file:
现在Q存储和提取时只需调用q些模块函数Q以下实例是个相当复杂的l构Q具有对同一嵌套对象的多重引用,该嵌套列表,即第1个LQ在文g中只会保存一ơ:
C:\...\PP3E\Dbase>python
>>> from filepickle import *
>>> L = [0]
>>> D = {'x':0, 'y':L}
>>> table = {'A':L, 'B':D} # L appears twice
>>> saveDbase('myfile', table) # serialize to file
C:\...\PP3E\Dbase>python
>>> from filepickle import *
>>> table = loadDbase('myfile') # reload/unpickle
>>> table
{'B': {'x': 0, 'y': [0]}, 'A': [0]}
>>> table['A'][0] = 1 # change shared object
>>> saveDbase('myfile', table) # rewrite to the file
C:\...\PP3E\Dbase>python
>>> from filepickle import *
>>> print loadDbase('myfile') # both L's updated as expected
{'B': {'x': 0, 'y': [1]}, 'A': [1]}
Besides
built-in types like the lists, tuples, and dictionaries of the examples
so far, class instances may also be pickled to file-like objects. This
provides a natural way to associate behavior with stored data (class
methods process instance attributes) and provides a simple migration
path (class changes made in module files are automatically picked up by
stored instances). Here's a brief interactive demonstration:
?
了内|的cdQ如以上例子中的列表Q元l和字典Q类实例也可被pickle到类似文件的对象中。这提供了一个自然的方式来关联行Z存储的数据(cL法处
理实例的属性)Qƈ提供了一条简单的q移路径Q被存储的实例将自动获得模块文g中对cȝ更改Q。以下是个简短的交互演示Q?
>>> class Rec:
def _ _init_ _(self, hours):
self.hours = hours
def pay(self, rate=50):
return self.hours * rate
>>> bob = Rec(40)
>>> import pickle
>>> pickle.dump(bob, open('bobrec', 'w'))
>>>
>>> rec = pickle.load(open('bobrec'))
>>> rec.hours
40
>>> rec.pay( )
2000
We'll
explore how this works in more detail in conjunction with shelves later
in this chapteras we'll see, although the pickle module can be used
directly, it is also the underlying translation engine in both shelves
and ZODB databases.
我们与本章下面的shelve一赯l探讨这是如此工作的。我们将会看刎ͼ虽然pickle模块可直接用,但它也是shelve和ZODB数据库的底层译引擎?
In fact, Python can pickle just about anything, except for:
事实上,Python可以pickleM东西Q除了:
Compiled
code objects; functions and classes record just their names in pickles,
to allow for later reimport and automatic acquisition of changes made
in module files.
~译的代码对象;函数和类在pickle中只是记录了它们的名字,以便后来重新导入和自动获取模块文件中的更攏V?
Instances
of classes that do not follow class importability rules (more on this
at the end of the section "Shelve Files," later in this chapter).
不遵守类可导入规则(class importability ruleQ的cd例(本章后面“Shelve文g”一节的N有更多相兛_容)?
Instances
of some built-in and user-defined types that are coded in C or depend
upon transient operating system states (e.g., open file objects cannot
be pickled).
用C~码的或依赖于操作系l瞬态的一些内|的和用户定义类型的实例Q例如,打开的文件对象无法pickleQ?
A PicklingError is raised if an object cannot be pickled.
如果对象不能pickleQ会引发PickleError?
19.4.3. Pickler Protocols and cPickle
19.4.3. Pickler协议和cPickle
In
recent Python releases, the pickler introduced the notion of
protocolsstorage formats for pickled data. Specify the desired protocol
by passing an extra parameter to the pickling calls (but not to
unpickling calls: the protocol is automatically determined from the
pickled data):
在最q的Python版本中,pickler推出了协议的概念Qpickle数据的保存格式。通过pickle调用时传入一个额外的参数Q可指定所需的协议(但unpickle调用不需要:协议是自动从已pickle的数据确定的Q:
pickle.dump(object, file, protocol)
Pickled
data may be created in either text or binary protocols. By default, the
storage protocol is text (also known as protocol 0). In text mode, the
files used to store pickled objects may be opened in text mode as in
the earlier examples, and the pickled data is printable ASCII text,
which can be read (it's essentially instructions for a stack machine).
Pickle
数据可以按文本协议或二进制协议生。默认情况下Q存储协议是文本协议Q也UCؓ0号协议)。在文本模式下,用来存储pickle对象的文件可以用文本模式
打开Q如上述的例子,q且pickle的数据是可打印的ASCII文本Qƈ且是可读的(q基本上是对堆栈机实现的指示Q?
The
alternative protocols (protocols 1 and 2) store the pickled data in
binary format and require that files be opened in binary mode (e.g.,
rb, wb). Protocol 1 is the original binary format; protocol 2, added in
Python 2.3, has improved support for pickling of new-style classes.
Binary format is slightly more efficient, but it cannot be inspected.
An older option to pickling calls, the bin argument, has been subsumed
by using a pickling protocol higher than 0. The pickle module also
provides a HIGHEST_PROTOCOL variable that can be passed in to
automatically select the maximum value.
?
他协议(1号和2号协?
Q以二进制格式存储pickle数据Qƈ要求文g以二q制模式打开Q例如:rb、wbQ?号协议是原始二进制格式;2号协议是Python
2.3增加的,它改善了Ҏ型类pickle的支持。二q制格式效率更高一点,但它无法q行查看。旧的pickle调用有一个选项Q即bin参数Q现已被
归入使用大于0的协议。pickle模块q提供了一个HIGHEST_PROTOCOL变量Q传入它可以自动选择最大的协议倹{?
One
note: if you use the default text protocol, make sure you open pickle
files in text mode later. On some platforms, opening text data in
binary mode may cause unpickling errors due to line-end formats on
Windows:
注意Q如果您使用默认的文本协议,以后请务必以文本模式打开pickle文g。在一些^CQ因为Windows的行格式不同,以二q制模式打开文本数据可能会导致unpickle错误:
>>> f = open('temp', 'w') # text mode file on Windows
>>> pickle.dump(('ex', 'parrot'), f) # use default text protocol
>>> f.close( )
>>>
>>> pickle.load(open('temp', 'r')) # OK in text mode
('ex', 'parrot')
>>> pickle.load(open('temp', 'rb')) # fails in binary
Traceback (most recent call last):
File "<pyshell#337>", line 1, in -toplevel-
pickle.load(open('temp', 'rb'))
...lines deleted...
ValueError: insecure string pickle
One
way to sidestep this potential issue is to always use binary mode for
your files, even for the text pickle protocol. Since you must open
files in binary mode for the binary pickler protocols anyhow (higher
than the default 0), this isn't a bad habit to get into:
回避q个潜在问题的方法之一是,L使用二进制模式的文gQ即使是用文本pickle协议。至对于二q制pickler协议Q高于默?Q,您必M二进制模式打开文gQ所以这不是一个坏习惯Q?
>>> f = open('temp', 'wb') # create in binary mode
>>> pickle.dump(('ex', 'parrot'), f) # use text protocol
>>> f.close( )
>>>
>>> pickle.load(open('temp', 'rb'))
('ex', 'parrot')
>>> pickle.load(open('temp', 'r'))
('ex', 'parrot')
Refer
to Python's library manual for more information on the pickler. Also
check out marshal, a module that serializes an object too, but can
handle only simple object types. pickle is more general than marshal
and is normally preferred.
请参考Python库手册,以了解更多pickler的信息。另外,h阅marshalQ它也是一个序列化对象的模块,但只能处理简单对象类型。pickle比marshal更通用Qƈ通常是首选?
And
while you are flipping (or clicking) through that manual, be sure to
also see the entries for the cPickle modulea reimplementation of pickle
coded in C for faster performance. You can explicitly import cPickle
for a substantial speed boost; its chief limitation is that you cannot
subclass its versions of Pickle and Unpickle because they are
functions, not classes (this is not required by most programs). The
pickle and cPickle modules use compatible data formats, so they may be
used interchangeably.
?
当你ȝQ或点击QPython手册Ӟ请一定也要看看cPickle模块的条目,它是pickle的C语言实现Q性能上更快。您可以昑ּ导入
cPickle替代pickleQ以大幅提升速度Q其主要的限制是Q你不能l承该版本的Pickle和UnpickleQ因为它们是函数Q而不是类Q多?
E序q不要求它们是类Q。pickle和cPickle模块使用兼容的数据格式,所以它们可以互换用?
If
it is available in your Python, the shelve module automatically chooses
the cPickle module for faster serialization, instead of pickle. I
haven't explained shelve yet, but I will now.