1.对象持久化
如果希望透明地存储 Python 对象,而不丢失其身份和类型等信息,则需要某种形式的对象序列化:
它是一个将任意复杂的对象转成对象的文本或二进制表示的过程。同样,必须能够将对象经过序列化后的形式恢复到原有的对象。
在 Python 中,这种序列化过程称为 pickle,可以将对象 pickle 成字符串、磁盘上的文件或者任何类似于文件的对象,也可以将这些字符串、文件或任何类似于文件的对象 unpickle 成原来的对象。
2. Pickle模块
pickle模块就是实现了这样功能的一个模块,代码如下:
In [3]: import cPickle as pickle
In [4]: a1=['apple','banana','orange']
In [5]: b1={'one':1,'two':2,'three':3}
In [6]: f=open('temp.pkl','wb')
In [7]: pickle.dump(a1,f)
In [8]: pickle.dump(b1,f)
In [9]: f.close()
In [10]: f2 = file('temp.pkl','rb')
In [11]: recover1 = pickle.load(f2)
In [12]: print recover1
['apple', 'banana', 'orange']
In [13]: recover2 = pickle.load(f2)
In [14]: print recover2
{'one': 1, 'three': 3, 'two': 2}
In [15]: f2.close()
3. ZODB
pickle 模块可以提供这些好处,但有时可能需要比这种简单的 pickle 文件更健壮以及更具有可伸缩性的事物。
例如,只用 pickle 不能解决命名和查找 pickle 文件这样的问题,另外,它也不能支持并发地访问持久性对象。如果需要这些方面的功能,则要求助类似于 ZODB(针对 Python 的 Z 对象数据库)这类数据库。
ZODB (Zope Object Database)是一个健壮的、多用户的和面向对象的数据库系统,它能够存储和管理任意复杂的 Python 对象,并支持事务操作和并发控制。
以下是一个模拟银行存款取款的小例子,使用ZODB来进行存储
customer.py 一个继承Persistent的Account类
import persistent
class OutOfFunds(Exception):
pass
class Account(persistent.Persistent):
def __init__(self,name,start_balance=0):
self.name = name
self.balance = start_balance
def __str__(self):
return "Account: %s, balance: %s" %(self.name,self.balance)
def __repr__(self):
return "Account: %s, balance: %s" %(self.name,self.balance)
def deposit(self,amount):
"""save amount into balance"""
self.balance += amount
def withdraw(self,amount):
"""withdraw from balance"""
if amount > self.balance:
raise OutOfFunds
self.balance -= amount
return self.balance
模拟银行存款取款 zodb_customer_app.py
import ZODB
import ZODB.FileStorage as ZFS
import transaction
import customer
class ZODBUtils:
conn = None
filestorage = None
def openConnection(self,file_name):
self.filestorage = ZFS.FileStorage(file_name)
db = ZODB.DB(self.filestorage)
self.conn = db.open()
return self.conn
def closeConnection(self):
self.conn.close()
self.filestorage.close()
def init_balance():
zodbutils = ZODBUtils()
conn = zodbutils.openConnection('zodb_filestorage.db')
root = conn.root()
noah = customer.Account('noah',1000)
print noah
root['noah'] = noah
jermy = customer.Account('jermy',2000)
print jermy
root['jermy'] = jermy
transaction.commit()
zodbutils.closeConnection()
def app():
zodbutils = ZODBUtils()
conn = zodbutils.openConnection('zodb_filestorage.db')
root = conn.root()
noah = root['noah']
print "Before Deposit Or Withdraw"
print "=" * 30
print noah
jermy = root['jermy']
print jermy
print '-' * 30
transaction.begin()
noah.deposit(300)
jermy.withdraw(300)
transaction.commit()
print "After Deposit Or Withdraw"
print "=" * 30
print noah
print jermy
print "-" * 30
zodbutils.closeConnection()
if __name__ == '__main__':
# init_balance()
app()
运行结果如下: