Python Tutorial 第三堂(3)永續化機制
|
Python Tutorial 第三堂(2)資料處理函式 << 前情 在 Python Tutorial 第一堂(4)中談過基本輸入輸出,除了利用基本 I/O 來保存運算結果之外,Python 中還提供了一些方式,可以直接保存物件狀態,在下次重新執行程式時讀取以恢復運算時必要的資料,在這邊要介紹幾個方式,像是 …
除此之外,你還可以透過第三方程式庫,進行物件關聯對應(Object-Relational Mapping),像是 SQLAlchemy、SQLObject,由於時間的關係,ORM 沒辦法在這節課做說明,不過稍後介紹 Django 時,會看到一些 ORM 的實際例子。 marshal、pickle 與 cPickle在物件序列化方面, 一般來說,如果要序列化 Python 物件,使用
來看看使用 class DVD:
def __init__(self, title, year=None,
duration=None, director_id=None):
self.title = title
self.year = year
self.duration = duration
self.director_id = director_id
self.filename = self.title.replace(' ', '_') + '.pkl'
def check_filename(self, filename):
if filename is not None:
self.filename = filename
這個 def save(self, filename=None):
self.check_filename(filename)
fh = None
try:
data = (self.title, self.year,
self.duration, self.director_id)
fh = open(self.filename, 'wb')
pickle.dump(data, fh)
except (EnvironmentError, pickle.PicklingError) as err:
raise SaveError(str(err))
finally:
if fh is not None:
fh.close()
最主要地,你要以 def load(self, filename=None):
self.check_filename(filename)
fh = None
try:
fh = open(self.filename, 'rb')
data = pickle.load(fh)
(self.title, self.year,
self.duration, self.director_id) = data
except (EnvironmentError, pickle.PicklingError) as err:
raise LoadError(str(err))
finally:
...
這次是讀取,因此你要用 filename = 'PyConTutorial2013.pkl'
dvd1 = DVD('PyCon Tutorial', 2013, 1, 'Justin Lin')
dvd1.save()
dvd2 = DVD('PyCon Tutorial')
dvd2.load()
print dvd2
DBMdbm 為柏克萊大學發展的檔案型資料庫,Python 的 在這邊直接轉貼 anydbm — Generic access to DBM-style databases 中的範例程式碼作個示範: import anydbm
# Open database, creating it if necessary.
db = anydbm.open('cache', 'c')
# Record some values
db['www.python.org'] = 'Python Website'
db['www.cnn.com'] = 'Cable News Network'
# Loop through contents. Other dictionary methods
# such as .keys(), .values() also work.
for k, v in db.iteritems():
print k, '\t', v
# Storing a non-string key or value will raise an exception (most
# likely a TypeError).
db['www.yahoo.com'] = 4
# Close when done.
db.close()
shelve 模組
class DvdDao:
def __init__(self, shelve_name):
self.shelve_name = shelve_name
def save(self, dvd):
shelve_db = None
try:
shelve_db = shelve.open(self.shelve_name)
shelve_db[dvd.title] = (dvd.year,
dvd.duration, dvd.director_id)
shelve_db.sync()
finally:
if shelve_db is not None:
shelve_db.close()
def all(self):
shelve_db = None
try:
shelve_db = shelve.open(self.shelve_name)
return [DVD(title, *shelve_db[title])
for title in sorted(shelve_db, key=str.lower)]
finally:
if shelve_db is not None:
shelve_db.close()
return []
def load(self, title):
shelve_db = None
try:
shelve_db = shelve.open(self.shelve_name)
if title in shelve_db:
return DVD(title, *shelve_db[title])
finally:
if shelve_db is not None:
shelve_db.close()
return None
def remove(self, title):
shelve_db = None
try:
shelve_db = shelve.open(self.shelve_name)
del shelve_db[title]
shelve_db.sync()
finally:
if shelve_db is not None:
shelve_db.close()
以下是個使用 filename = 'dvd_library.slv'
dao = DvdDao(filename)
dvd1 = DVD('PyCon Tutorial 2012', 2012, 1, 'Justin Lin')
dvd2 = DVD('PyCon Tutorial 2013', 2013, 1, 'Justin Lin')
dao.save(dvd1)
dao.save(dvd2)
print dao.all()
print dao.load('PyCon Tutorial 2012')
dao.remove('PyCon Tutorial 2013')
print dao.all()
DB-API 2.0(PEP 249)為 Python 中存取資料庫的標準介面,就我的認知而言,其角色應該是類似於 Java 中的 JDBC。Python 中的 以下直接列出範例程式碼,程式很簡單,應該一目瞭然,API 細節可參考 sqlite3 — DB-API 2.0 interface for SQLite databases。 def connect(name):
create = not os.path.exists(name)
conn = sqlite3.connect(name)
if create:
cursor = conn.cursor()
cursor.execute("CREATE TABLE directors ("
"id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, "
"name TEXT UNIQUE NOT NULL)")
cursor.execute("CREATE TABLE dvds ("
"id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL, "
"title TEXT NOT NULL, "
"year INTEGER NOT NULL, "
"duration INTEGER NOT NULL, "
"director_id INTEGER NOT NULL, "
"FOREIGN KEY (director_id) REFERENCES directors)")
conn.commit()
return conn
def add_dvd(conn, title, year, duration, director):
director_id = get_and_set_director(conn, director)
cursor = conn.cursor()
cursor.execute("INSERT INTO dvds "
"(title, year, duration, director_id) "
"VALUES (?, ?, ?, ?)",
(title, year, duration, director_id))
conn.commit()
def get_and_set_director(conn, director):
director_id = get_director_id(conn, director)
if director_id is not None:
return director_id
cursor = conn.cursor()
cursor.execute("INSERT INTO directors (name) VALUES (?)",
(director,))
conn.commit()
return get_director_id(conn, director)
def get_director_id(conn, director):
cursor = conn.cursor()
cursor.execute("SELECT id FROM directors WHERE name=?",
(director,))
fields = cursor.fetchone()
return fields[0] if fields is not None else None
def all_dvds(conn):
cursor = conn.cursor()
sql = ("SELECT dvds.title, dvds.year, dvds.duration, "
"directors.name FROM dvds, directors "
"WHERE dvds.director_id = directors.id"
" ORDER BY dvds.title")
cursor.execute(sql)
return [(str(fields[0]), fields[1], fields[2], str(fields[3]))
for fields in cursor]
def all_directors(conn):
cursor = conn.cursor()
cursor.execute("SELECT name FROM directors ORDER BY name")
return [str(fields[0]) for fields in cursor]
以下是個存取資料庫的例子: db_name = 'dvd_library.sqlite3' conn = connect(db_name) add_dvd(conn, 'Python Tutorial 2013', 2013, 1, 'Justin') print all_directors(conn) print all_dvds(conn) 練習 8:永續化機制 在 Lab 檔案中有個 lab/exercises/exercise8,當中有 pickle、shelve、sql 三個資料夾,分別是上頭三個程式範例,不過程式碼內容不完整,請任選你想要練習的對象,按加上頭列出的範例程式碼,就不齊全的部份補齊。 完成這個練習後,第三堂應該時間就差不多到了,休息一下,接下來的第三堂課要來認識 Python 的 Web 框架 … 參考資源
* http://www.python.org/~guido/
* http://docs.python.org/2.7/
* http://docs.python.org/2.7/library/functions.html
* http://docs.python.org/2/library/pickle.html 後續 >> Python Tutorial 第四堂(1)Django 起步走
|

Java 學習之路





