Python 的開發環境

建議在Windows 下開發,成本低廉,簡單,效率高。html

綜合下:開發的程序,Python  Django (Mysql,PostgreSQL) Nginx Redis ,這一組組合能夠適應不一樣的平臺,Linux 或者 Windows Server 下。。前端

 

Python版本:node

推薦2.X系列,2.7是用的較多的。3.0N多不兼容。。。。想嚐鮮的,呵呵呵呵python

 

Windows-->Visual Studio2013 +PTVS2.2nginx

Mac -->Xcode git

Linux -->vi pycharm ......呵呵呵呵web

 

也有用Pycharm 或者Eclipse的,親身試試就知道那款合適了。不作比較。算法

小貼士:SharpDevelop_3.1。。。。。用這個來進行C# 項目代碼的轉化,你懂得。。。。sql

 

Web 框架:Django,Web.py 其餘不考慮呵呵呵,你懂數據庫

數據庫:Mysql Pgsql (Sqlite 額太mini,袖珍。Oracle 略貴 SqlServer 額,僅Windows.................MonoDB  Nosql 等等等,爭議太多,不要圖新鮮,作試驗品)

緩存:Memcached 或者Redis 

Server:Nginx -->OpenResty

OpenResty - a fast web app server by extending nginx

、Tornado、Apache

 

前端:Jquery、 bootstrap、 kando 

源碼管理:vs  的 直接TFS,也可換成git  

 

ORM工具:Django自帶的或者 SQLAlchemy

 

序列化爭議:

pickle和cPickle:Python對象的序列化(上)

pickle和cPickle:Python對象的序列化(下)

 

JianZhenJianZhen  275 1月17日 發佈
  •  1 推薦
  •  4 收藏,2k 瀏覽

目的:Python對象序列化
可用性:pickle至少1.4版本,cPickle 1.5版本以上


pickle模塊實現了一種算法,將任意一個Python對象轉化成一系列字節(byets)。此過程也調用了serializing對象。表明對象的字節流以後能夠被傳輸或存儲,再重構後建立一個擁有相同特徵(the same characteristics)的新的對象。

cPickle使用C而不是Python,實現了相同的算法。這比Python實現要快好幾倍,可是它不容許用戶從Pickle派生子類。若是子類對你的使用來講可有可無,那麼cPickle是個更好的選擇。

警告:本文檔直接說明,pickle不提供安全保證。若是你在多線程通訊(inter-process communication)或者數據存儲或存儲數據中使用pickle,必定要當心。請勿信任你不能肯定爲安全的數據。

導入

如日常同樣,嘗試導入cPickle,給它賦予一個別名「pickle」。若是由於某些緣由導入失敗,退而求其次到Python的原生(native)實現pickle模塊。若是cPickle可用,能給你提供一個更快速的執行,不然只能是輕便的執行(the portable implementation)。

try: import cPickle as pickle except: import pickle 

編碼和解碼

第一個例子將一種數據結構編碼成一個字符串,而後把該字符串打印至控制檯。使用一種包含全部原生類型(native types)的數據結構。任何類型的實例均可被醃漬(pickled,譯者注:模塊名稱pickle的中文含義爲醃菜),在稍後的例子中會演示。使用pickle.dumps()來建立一個表示該對象值的字符串。

try: import cPickle as pickle except: import pickle import pprint data = [ { 'a':'A', 'b':2, 'c':3.0 } ] print 'DATA:', pprint.pprint(data) data_string = pickle.dumps(data) print 'PICKLE:', data_string 

pickle默認僅由ASCII字符組成。也可使用更高效的二進制格式(binary format),只是由於在打印的時候更易於理解,本頁的全部例子都使用ASCII輸出。

$ python pickle_string.py

DATA:[{'a': 'A', 'b': 2, 'c': 3.0}] PICKLE: (lp1 (dp2 S'a' S'A' sS'c' F3 sS'b' I2 sa. 

數據被序列化之後,你能夠將它們寫入文件、套接字、管道等等中。以後你也能夠從文件中讀取出來、將它反醃漬(unpickled)而構造一個具備相同值得新對象。

try: import cPickle as pickle except: import pickle import pprint data1 = [ { 'a':'A', 'b':2, 'c':3.0 } ] print 'BEFORE:', pprint.pprint(data1) data1_string = pickle.dumps(data1) data2 = pickle.loads(data1_string) print 'AFTER:', pprint.pprint(data2) print 'SAME?:', (data1 is data2) print 'EQUAL?:', (data1 == data2) 

如你所見,這個新構造的對象與原對象相同,但並不是同一對象。這不足爲奇。

$ python pickle_unpickle.py

BEFORE:[{'a': 'A', 'b': 2, 'c': 3.0}] AFTER:[{'a': 'A', 'b': 2, 'c': 3.0}] SAME?: False EQUAL?: True 

與流一塊兒工做

dumps()loads()外,pickle還提供一對用在類文件流(file-like streams)的轉化函數。能夠往一個流中寫對個對象,而後從流中把它們讀取出來,此過程不須要預先寫入的對象有幾個、它們多大。

try: import cPickle as pickle except: import pickle import pprint from StringIO import StringIO class SimpleObject(object): def __init__(self, name): self.name = name l = list(name) l.reverse() self.name_backwards = ''.join(l) return data = [] data.append(SimpleObject('pickle')) data.append(SimpleObject('cPickle')) data.append(SimpleObject('last')) # 使用StringIO模擬一個文件 out_s = StringIO() # 寫入該流 for o in data: print 'WRITING: %s (%s)' % (o.name, o.name_backwards) pickle.dump(o, out_s) out_s.flush() # 創建一個可讀流 in_s = StringIO(out_s.getvalue()) # 讀數據 while True: try: o = pickle.load(in_s) except EOFError: break else: print 'READ: %s (%s)' % (o.name, o.name_backwards) 

這個例子使用SringIO緩存器(buffer)模擬流,因此在創建可讀流的時候咱們玩了一把。一個簡單數據庫的格式化也可使用pickles來存儲對象,只是shelve與之工做更加簡便。

$ python pickle_stream.py

WRITING: pickle (elkcip)
WRITING: cPickle (elkciPc)
WRITING: last (tsal)
READ: pickle (elkcip)
READ: cPickle (elkciPc)
READ: last (tsal)

除了存儲數據,pickles在進程間通訊(inter-process communication)中也很是稱手。例如,使用os.fork()os.pipe()能夠創立工做者進程(worker processes),從一個管道(pipe)讀取做業指令(job instruction)而後將結果寫入另外一個管道。管理工做者池(worker pool)和將做業送入、接受響應(response)的核心代碼可被重用,由於做業和響應並不屬於某個特定類中。若是你使用管道或者套接字(sockets),在經過連至另外一端(end)的鏈接傾倒(dumps)全部對象、推送數據以後,別忘了沖洗(flush)。若是你想寫本身的工做者池管理器,請看multiprocessing

原文:pickle and cPickle – Python object serialization - Python Module of the Week 的前半部分

 

  •  0 推薦
  •  2 收藏,474 瀏覽

承接上文 pickle和cPickle:Python對象的序列化(上) 。

重構對象的問題

當與你本身的類一塊兒工做時,你必須保證類被醃漬出如今讀取pickle的進程的命名空間中。只有該實例的數據而不是類定義被醃漬。類名被用於在反醃漬時,找到構造器(constructor)以建立新對象。以此——往一個文件寫入一個類的實例爲例:

try: import cPickle as pickle except: import pickle import sys class SimpleObject(object): def __init__(self, name): self.name = name l = list(name) l.reverse() self.name_backwards = ''.join(l) return if __name__ == '__main__': data = [] data.append(SimpleObject('pickle')) data.append(SimpleObject('cPickle')) data.append(SimpleObject('last')) try: filename = sys.argv[1] except IndexError: raise RuntimeError('Please specify a filename as an argument to %s' % sys.argv[0]) out_s = open(filename, 'wb') try: # 寫入流中 for o in data: print 'WRITING: %s (%s)' % (o.name, o.name_backwards) pickle.dump(o, out_s) finally: out_s.close() 

在運行時,該腳本建立一個以在命令行指定的參數爲名的文件:

$ python pickle_dump_to_file_1.py test.dat

WRITING: pickle (elkcip)
WRITING: cPickle (elkciPc)
WRITING: last (tsal)

一個在讀取結果醃漬對象失敗的簡化嘗試:

try: import cPickle as pickle except: import pickle import pprint from StringIO import StringIO import sys try: filename = sys.argv[1] except IndexError: raise RuntimeError('Please specify a filename as an argument to %s' % sys.argv[0]) in_s = open(filename, 'rb') try: # 讀取數據 while True: try: o = pickle.load(in_s) except EOFError: break else: print 'READ: %s (%s)' % (o.name, o.name_backwards) finally: in_s.close() 

該版本失敗的緣由在於沒有 SimpleObject 類可用:

$ python pickle_load_from_file_1.py test.dat

Traceback (most recent call last):
  File "pickle_load_from_file_1.py", line 52, in <module> o = pickle.load(in_s) AttributeError: 'module' object has no attribute 'SimpleObject' 

正確的版本從原腳本中導入 SimpleObject ,可成功運行。
添加:

from pickle_dump_to_file_1 import SimpleObject 

至導入列表的尾部,接着從新運行該腳本:

$ python pickle_load_from_file_2.py test.dat

READ: pickle (elkcip)
READ: cPickle (elkciPc)
READ: last (tsal)

當醃漬有值的數據類型不能被醃漬時(套接字、文件句柄(file handles)、數據庫鏈接等之類的),有一些特別的考慮。由於使用值而不能被醃漬的類,能夠定義 __getstate__() 和 __setstate__() 來返回狀態(state)的一個子集,才能被醃漬。新式類(New-style classes)也能夠定義__getnewargs__(),該函數應當返回被傳遞至類內存分配器(the class memory allocator)(C.__new__())的參數。使用這些新特性的更多細節,包含在標準庫文檔中。

環形引用(Circular References)

pickle協議(pickle protocol)自動處理對象間的環形引用,所以,即便是很複雜的對象,你也不用特別爲此作什麼。考慮下面這個圖:

上圖雖然包括幾個環形引用,但也能以正確的結構醃漬和從新讀取(reloaded)。

import pickle class Node(object): """ 一個全部結點均可知它所連通的其它結點的簡單有向圖。 """ def __init__(self, name): self.name = name self.connections = [] return def add_edge(self, node): "建立兩個結點之間的一條邊。" self.connections.append(node) return def __iter__(self): return iter(self.connections) def preorder_traversal(root, seen=None, parent=None): """產生器(Generator )函數經過一個先根遍歷(preorder traversal)生成(yield)邊。""" if seen is None: seen = set() yield (parent, root) if root in seen: return seen.add(root) for node in root: for (parent, subnode) in preorder_traversal(node, seen, root): yield (parent, subnode) return def show_edges(root): "打印圖中的全部邊。" for parent, child in preorder_traversal(root): if not parent: continue print '%5s -> %2s (%s)' % (parent.name, child.name, id(child)) # 建立結點。 root = Node('root') a = Node('a') b = Node('b') c = Node('c') # 添加邊。 root.add_edge(a) root.add_edge(b) a.add_edge(b) b.add_edge(a) b.add_edge(c) a.add_edge(a) print 'ORIGINAL GRAPH:' show_edges(root) # 醃漬和反醃漬該圖來建立 # 一個結點集合。 dumped = pickle.dumps(root) reloaded = pickle.loads(dumped) print print 'RELOADED GRAPH:' show_edges(reloaded) 

從新讀取的諸多節點(譯者注:對應圖中的圓圈)再也不是同一個對象,可是節點間的關係保持住了,並且讀取的僅僅是帶有多個引用的對象的一個拷貝。上面所說的能夠經過測試各節點在pickle處理前和以後的id()值來驗證。

$ python pickle_cycle.py

ORIGINAL GRAPH:
 root ->  a (4299721744) a -> b (4299721808) b -> a (4299721744) b -> c (4299721872) a -> a (4299721744) root -> b (4299721808) RELOADED GRAPH: root -> a (4299722000) a -> b (4299722064) b -> a (4299722000) b -> c (4299722128) a -> a (4299722000) root -> b (4299722064) 

原文 pickle and cPickle – Python object serialization - Python Module of the Week 的後半部分。

相關文章
相關標籤/搜索