精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

使用Oracle數據庫實現Python數據持久

數據庫 Oracle 后端
本文借助一個示例讓您了解如何采用互補的方法嘗試將oracle和python結合使用。

盡管Python 很快在開發人員之中普及,但長久以來 Oracle 數據庫一直是最出色的企業級數據庫。采用有效的方式將這兩者結合在一起是比較令人感興趣的主題,但這實際上是真正的挑戰,因為二者都要付出很多。

盡管受到警告,但本文并不會對最杰出的 Python 和 Oracle 數據庫特性進行概述,而是提供一系列獨立的示例。本文借助一個示例讓您了解如何采用互補的方法嘗試將這兩種技術結合使用。尤其是,本文將指導您利用 PL/SQL 存儲過程(在 Python 腳本中編排其調用)創建 Oracle 支持的 Python 應用程序,該應用程序在 Python 和數據庫中實施業務邏輯。

正如您將在本文中學習到的,即使是輕型的 Oracle 數據庫 10g 快捷版 (XE) 也可以得到有效利用,作為數據驅動的 Web 應用程序的數據庫后端,其前端層使用 Python 構建。特別是,Oracle 數據庫 XE 支持 Oracle XML DB,這是構建 Web 應用程序時通常需要的一組 Oracle 數據庫 XML 技術。

示例應用程序

在用戶使用您的應用程序時收集有關用戶執行操作的信息成為一種比較流行的接收用戶反饋的機制。通常,相對于讓用戶明確表達偏好的任何調查來說,并入在線應用程序中的點擊跟蹤工具可以為您提供有關用戶偏好的大量信息。

舉一個簡單的例子,假設您想從“OTN — 新文章 RSS”頁面中選取三個最新的 Oracle 技術網 (OTN) 文章標題,并將這些鏈接放到您的站點上。然后,您希望收集有關用戶在您的站點上跟隨這些鏈接中的每個鏈接的次數的信息。這就是我們的示例將要做的。現在,讓我們試著弄清如何實現所有這些功能。首先,必須決定如何在應用程序層之間分發業務邏輯。實際上,決定如何在應用程序層之間分發業務邏輯可能是規劃數據庫驅動的應用程序最具挑戰性的部分。盡管執行業務邏輯通常有多種方法,但是您的工作是找到最有效的方法。作為一般的經驗,當規劃數據庫驅動的應用程序時,您應該認真考慮數據庫中關鍵數據處理邏輯的實現。這種方法可以幫助您削減與在 Web 服務器和數據庫之間發送數據相關的網絡開銷,并且可以減輕 Web 服務器的負擔。

將所有這些理論應用到我們的示例上,例如,將獲得插入到數據庫中的文章詳細信息的負擔放到在數據庫中創建的存儲過程上,這樣 Web 服務器不必再處理與維護數據完整性有關的任務。這在實踐中的意義是您不必編寫特定 Python 代碼,這些代碼負責跟蹤數據庫中是否存在與其鏈接被點擊的文章有關的記錄,如果不存在,則插入該記錄,然后從“OTN — 新文章 RSS”頁面中獲取所需的所有詳細信息。通過讓數據庫自己跟蹤此類事情,您可以獲得具有更高可擴展性且更不易出錯的解決方案。在本例中,Python 代碼將只負責從 RSS 頁面獲取文章鏈接,并在用戶單擊某個文章鏈接時向數據庫發送一條消息。

圖 1 給出了示例組件如何彼此交互以及如何與外部源交互的圖形描述。
 

圖 1:示例應用程序工作原理的高級視圖。
 

本文的其余部分介紹如何實現此示例應用程序。有關如何設置和啟動此示例的簡要描述,可以參考示例代碼根目錄下的 readme.txt 文件。

準備工作環境

要構建此處討論的示例,您需要安裝以下軟件組件(參見 Downloads portlet)并使其在您的系統中正常工作:

Apache HTTP Server 2.x

Oracle 數據庫 10g 快捷版

Python 2.5 或更高版本

mod_python 模塊

cx_Oracle 模塊

有關如何安裝上述組件的詳細說明,可以參考另一篇 OTN 文章“為 Python Server Pages 和 Oracle 構建快速 Web 開發環境”(作者:Przemyslaw Piotrowski)。

#p#

設計基礎數據庫

一般來說,最好從設計基礎數據庫開始。假設您創建了一個用戶模式并授予其創建和操作模式對象所需的所有權限,那么第一步就是創建基礎表。在這種特殊情況下,您將需要一個唯一的名為 otn_articles_rss 的表,創建該表的方式如下:

CREATE TABLE otn_articles_rss (
  guid VARCHAR2(100) PRIMARY KEY,
  title VARCHAR2(200),
  pubDate VARCHAR2(32),
  link VARCHAR2(200),
  clicks INTEGER
  );

下一步是設計一個將在 Python 代碼中調用的名為 count_clicks 的存儲過程,它更新 otn_articles_rss 表中的數據。繼續 count_clicks 過程之前,您必須先回答以下問題:當 count_clicks 嘗試更新尚未插入到 otn_articles_rss 表中的文章記錄的 clicks 字段時,會發生什么情況呢?假設一個新項目剛剛添加到 RSS 頁面,然后指向該項目的鏈接出現在您的站點上。當有人單擊該鏈接時,系統將從負責處理指向 OTN 文章的鏈接上執行的單擊次數的 Python 代碼中調用 count_clicks PL/SQL 過程。顯然,處理第一次單擊時,在 count_clicks 過程中發出的 UPDATE 語句將失敗,因為現在還沒有要更新的行。

要適應此類情況,您可以在 count_clicks 過程中實現一個 IF 塊,如果由于 UPDATE 找不到指定的記錄而將 SQL%NOTFOUND 屬性設置為 TRUE 時,該塊會發揮作用。在該 IF 塊中,只要指定了 guid 和單擊次數,您就可以先將一個新行插入到 otn_articles_rss 表中。之后,您應該提交這些更改,以便這些更改立即可用于其他用戶會話,這些會話可能也需要更新新插入的文章記錄的 clicks 字段。最后,您應該更新該記錄,設置其 title、pubDate 和 link 字段。該邏輯可以作為一個單獨的過程(比如 add_article_details)來實現,該過程的創建方式如下:

CREATE OR REPLACE PROCEDURE add_article_details (gid VARCHAR2, clks NUMBER) AS
  item XMLType;
  heading VARCHAR2(200);
  published VARCHAR2(32);
  url VARCHAR2(200);
  BEGIN
  SELECT extract(httpuritype.createuri(  
'http://feeds.delicious.com/v2/rss/OracleTechnologyNetwork/otntecharticle').getXML(),
  '//item[contains(guid, "'||gid||'")>0]')
  INTO item FROM DUAL;
  SELECT extractValue(item, '//title'),
  extractValue(item, '//pubDate'),
  extractValue(item, '//link')
  INTO heading, published, url FROM DUAL;
  UPDATE otn_articles_rss SET
  title = heading,
  pubDate = published,
  link = url,
  clicks = clicks + clks
  WHERE guid = gid;
  END;
  /

正如您所見,該過程接受兩個參數。gid 是其鏈接受到單擊的文章的 guid。clks 是文章查看總次數的增量。在該過程主體中,您獲得 RSS 文檔的所需部分作為 XMLType 實例,然后提取信息,之后該信息將立即用于填充 otn_articles_rss 中與正在處理的 RSS 項目關聯的記錄。

借助 add_article_details,您可以繼續下一環節,按照如下方式創建 count_clicks 過程:

CREATE OR REPLACE PROCEDURE count_clicks (gid VARCHAR2, clks NUMBER) AS
  BEGIN
  UPDATE otn_articles_rss SET
  clicks = clicks + clks
  WHERE guid = gid;
  IF SQL%NOTFOUND THEN
  INSERT INTO otn_articles_rss(guid, clicks) VALUES(gid, 0);
  COMMIT;
  add_article_details (gid, clks);
  END IF;
  COMMIT;
  END;
  /

事務考慮事項

在上面清單中所示的 count_clicks 存儲過程中,注意 COMMIT 的使用要緊跟在 INSERT 語句之后。最重要的是,之后要調用 add_article_details,其執行時間可能較長。通過在這個階段提交,新插入的文章記錄立即用于其他可能的更新,否則要等待 add_article_details 完成。

考慮以下示例。假設 RSS 頁面剛剛更新并且一個全新的文章鏈接變為可用。接下來,兩個不同的用戶加載您的頁面并幾乎同時單擊這個新鏈接。因此,將進行兩個對 count_clicks 的同時調用。在本例中,首先發生的調用將一條新記錄插入到 otn_articles_rss 表中,然后它將調用 add_article_details。雖然正在執行 add_article_details,但對 count_clicks 的另一個調用可以成功執行更新操作,增加總單擊次數。但是,如果此處忽略了 COMMIT,那么第二個調用將找不到用于更新的行,因此嘗試執行另一個插入。事實上,這將導致不可預測的結果。它將導致獨特的違反約束的錯誤,并且會丟失將第二次 count_clicks 調用進行的更新。

此處最令人感興趣的部分是在 count_clicks 過程主體結尾處執行另一個 COMMIT 操作。正如您所猜測的,需要在這個階段提交以便從更新的記錄中去除鎖定,從而使該記錄立即可用于其他會話執行的更新。有些人可能會說這個方法降低了靈活性,使客戶端無法根據自己的判斷提交或回滾事務。但是,在這種特殊的情況下,這并不是一個大問題,因為無論如何從調用 count_clicks 開始的事務都應該立即提交。這是因為當用戶單擊某個文章鏈接以離開您的頁面時,始終會調用 count_clicks。

構建前端層

既然已經創建了存儲過程并且準備好在應用程序中使用,那么您必須弄清如何從前端層編排在數據庫中實現的所有這些應用程序邏輯片段所執行的整個操作流。這就是 Python 派上用場的地方了。

我們先來看一個簡單的實現。為了開始,您必須編寫一些 Python 代碼,這些代碼將負責從“OTN — 新文章 RSS”頁面獲取數據。然后,您將需要開發一些代碼,這些代碼將處理在 Web 頁面中的 OTN 文章鏈接上執行的單擊。最后,您將需要構建該 Web 頁面本身。為此,您可能會使用 Python 的一種服務器端技術,比如 Python Server Pages (PSP),這使得將 Python 代碼嵌入到 HTML 中成為可能。

為了編寫 Python 代碼,您可以使用您喜歡的文本編輯器,如 vi 或記事本。創建一個名為 oraclepersist.py 的文件,然后在其中插入以下代碼,將該文件保存到 Python 解釋器可以找到的位置:

import cx_Oracle
  import urllib2
  import xml.dom.minidom
  def getRSS(addr):
  xmldoc = xml.dom.minidom.parseString(urllib2.urlopen(addr).read())
  items = xmldoc.getElementsByTagName('item')
  return items
  def getLatestItems(items, num):
  latest=[]
  inxs = ['title','guid','pubDate','link']
  myitems = [item for index, item in enumerate(items) if index < num]
  for item in myitems:
   latest.append(dict(zip(inxs,[item.getElementsByTagName(inx)[0].firstChild.data for inx in inxs])))
  return latest

正如您所猜測的,上面所示的 getRSS 函數將用來從 RSS 頁面獲取數據,并將該數據作為一個 DOM 對象返回。getLatestItems 專門用來處理該 DOM 文檔,將該文檔轉換為 Python dictionary 對象。

在 getLatestItems 函數中,注意列表內涵(一個新的 Python 語言特性)的使用,它提供了一種出色的方法,可顯著簡化數據處理任務的編碼。

下一步涉及一些代碼的創建,這些代碼將處理在指向 OTN 文章的鏈接上執行的單擊,這些鏈接是從“OTN — 新文章 RSS”頁面中獲取并放置到 Web 頁面上的。為此,您可以開發另一個自定義 Python 函數(比如說 processClick),每次用戶單擊您 Web 頁面上的 OTN 文章鏈接時都會調用該函數。要實現 processClick,將以下代碼添加到 oraclepersist.py:

def processClick(guid, clks = 1):
  db = cx_Oracle.connect('usr', 'pswd', '127.0.0.1/XE')
  c = db.cursor()
  c.execute('''call count_clicks(:guid, :clks)''', {'guid':guid, 'clks':clks})
  db.close()

以上代碼提供了實際運行的 cx_Oracle 的一個簡單示例。它首先連接到基礎數據庫。然后,它獲得一個 Cursor 對象,之后使用該對象的 execute 方法調用在之前的“設計基礎數據庫”部分討論的 count_clicks 存儲過程。

現在,您可以繼續下一環節,構建 Web 頁面。由于這是僅用于演示的應用程序,因此該頁面可能非常簡單,只包含從 RSS 頁面獲得的鏈接。在 APACHE_HOME/htdocs 目錄中,創建一個名為 clicktrack.psp 的文件,然后在其中插入以下代碼:

﹤html﹥
﹤head﹥
﹤meta http-equiv="Content-Type"  content="text/html; charset=UTF-8"﹥
﹤title﹥latest OTN articles﹤/title﹥
﹤/head﹥
﹤body﹥
﹤h2﹥Three most latest OTN  articles﹤/h2﹥
﹤%import oraclepersist
url =  'http://feeds.delicious.com/v2/rss/OracleTechnologyNetwork/otntecharticle'
doc = oraclepersist.getRSS(url)
articles =  oraclepersist.getLatestItems(doc, 3)
for article in articles:
%﹥
﹤% import urllib %﹥
﹤a href=﹤%= str(article['link'])  %﹥
    onclick = "this.href =  '/dispatcher.psp?url=﹤%=urllib.quote_plus(article['link'])+str('&guid=')+urllib.quote_plus(article['guid'])  %﹥'"﹥
       ﹤%=str(article['title']) %﹥
﹤/a﹥﹤br/﹥
﹤%
%﹥
﹤/body﹥
﹤/html﹥

 

正如您所見,以上文檔包含幾個嵌入的 Python 代碼塊。在第一個塊中,您從之前按照該部分所述創建的 oraclepersist 模塊調用函數,獲得列表的一個實例,該列表的項目代表三篇最新的 OTN 文章。然后,在 for 循環中循環該列表,為該列表中存在的每個文章項目生成一個鏈接。令人感興趣的是,盡管這些鏈接中的每個鏈接都引用相應的 OTN 文章地址,但是鏈接的 onclick 處理程序將動態修改鏈接到 dispatcher.psp 頁面的目標,該目標需要在 APACHE_HOME/htdocs 目錄中創建。將兩個參數(即 guid 和 url)附加到每個動態生成的鏈接,向 dispatcher.psp 提供有關正在加載的文章的信息。

以下是 dispatcher.psp 的代碼:

﹤html﹥
﹤body﹥
﹤%
import oraclepersist
import urllib
from mod_python import util
params = util.FieldStorage(req)
oraclepersist.processClick(urllib.unquote_plus(params['guid'].value),  1)
psp.redirect(urllib.unquote_plus(params['url'].value))
%﹥
﹤/body﹥
﹤/html﹥

在以上代碼中,借助 FieldStorage 類的幫助訪問了附加到 URL 的參數,該類來自 mod_python 網頁上提供的 Mod_python 手冊中描述的 util 模塊。然后,從我們的 oraclepersist 自定義模塊中調用 processClick 函數,將從 URL 中提取的 guid 作為第一個參數傳遞,將 1(意味著一次單擊)作為第二個參數傳遞。最后,將您的瀏覽器重定向到要加載的文章的位置。

現在,可以測試這個應用程序了。由于您處理的是實時數據,因此您必須連接到互聯網。建立連接之后,將瀏覽器指向 http://localhost/clicktrack.psp。因此,應該出現一個包含指向 OTN 最新文章的三個鏈接的簡單 Web 頁面。如圖 2 所示。

圖 2:這是加載時的應用程序頁面。

 

單擊任一文章鏈接并查看所發生的情況。從用戶的角度,您將只看到文章正加載到瀏覽器中,如圖 3 所示。

 

圖 3:當跟隨應用程序頁面上的文章鏈接時,用戶只能看到文章本身。

負責收集有關單擊信息的代碼將在后臺運行。為了確保該代碼已經這樣操作,您可以連接到基礎數據庫并發出以下查詢:

SELECT * FROM otn_articles_rss;

甚至在完全加載文章文檔之前,上述代碼應該輸出一個包含有關正在加載的文章信息的行,在 clicks 字段中顯示 1。隨后對此鏈接進行的每個單擊將使 clicks 字段的值增加 1。
#p#

采用Pythonic 方法

在前面部分中編寫的代碼結構與采用 Pythonic 方法實現的代碼看起來不太相同。尤其是,您按照一定的順序實現了一組將從在 HTML 中嵌入的代碼調用的函數,將一個函數返回的結果用作另一個函數的參數。實際上,這是采用任何其他腳本語言(比如說 PHP)結構化您的代碼的方式。

盡管 Python 的真正功能在于它能夠隱藏令人厭煩的實現詳細信息,從而提供一個簡單、優美而有效的編碼解決方案。字典、列表和列表內涵是常用的 Python 內置類型,在處理結構化數據時可以顯著簡化您的代碼。返回在前面部分中討論的 oraclepersist.py 腳本,對其進行升級,以便最大程度地利用這些杰出的 Python 語言工具。為了避免混淆,您可以將修訂保存在一個單獨的名為 oraclepersist_list.py 的文件中:

import cx_Oracle
  import urllib2
  import xml.dom.minidom
  url = 'http://feeds.delicious.com/v2/rss/OracleTechnologyNetwork/otntecharticle'
  inxs = ['title','guid','pubDate','link']
  num = 3
  def getRSS(addr):
  xmldoc = xml.dom.minidom.parseString(urllib2.urlopen(addr).read())
  items = xmldoc.getElementsByTagName('item')
  return items
  articles = [dict(zip(inxs,[item.getElementsByTagName(inx)[0].firstChild.data for inx in inxs])) for index, item in enumerate(getRSS(url)) if index < num]
  def processClick(guid, clks = 1):
  db = cx_Oracle.connect('usr', 'pswd', '127.0.0.1/XE')
  c = db.cursor()
  c.execute('''call count_clicks(:guid, :clks)''', {'guid':guid, 'clks':clks})
  db.close()

從以上代碼可以看出,利用列表內涵(一種非常有效的結構化應用程序數據的機制)可以顯著減少代碼總量。此外,客戶端也不必顯式調用模塊函數。因此,您現在可以重新編寫按照前面部分所述嵌入在 clicktrack.psp 中的 Python 代碼塊,如下所示:

...
﹤%import oraclepersist_list
for article in oraclepersist_list.articles:
%﹥
...

 

盡管現在它更為簡潔,但用戶不需要進行任何更改。

但是,有人可能會說將 PSP 頁面中的代碼與其后端連接實在不是一個靈活的方法。例如,將要顯示的鏈接數量以及要使用的 RSS 地址硬編碼到 oraclepersist_list.py 腳本中,借助這個新的語法,您無法根據需要動態更改這些參數。要解決此問題,可以將列表內涵封裝在 oraclepersist_list.py 腳本中的某個函數中,如下所示:

...
  def getLatestItems(num = 3, url = 'http://feeds.delicious.com/v2/rss/OracleTechnologyNetwork/otntecharticle'):
  inxs = ['title','guid','pubDate','link']
  return [dict(zip(inxs,[item.getElementsByTagName(inx)[0].firstChild.data for inx in inxs])) for index, item in enumerate(getRSS(url)) if index < num]
  ...

  正如您所見,以上代碼仍然利用了基于使用列表內涵、列表和字典的高級語法,從而允許在 clicktrack.psp 頁面中動態更改參數。以下代碼片段將闡釋現在如何顯式指定要顯示的文章鏈接數量:

...
﹤%import oraclepersist_list
for article in  oraclepersist_list.getLatestItems(5):
%﹥
...

使用面向對象的方法

盡管 Python 中的面向對象編程 (OOP) 是完全可選的,但利用該范例可以最大程度地減少冗余,高效地自定義現有代碼。與其他現代語言一樣,Python 允許您使用類封裝邏輯和數據,簡化了數據定義和數據操作。

回到在前面部分中討論的 oraclepersist_list.py 腳本,將 processClick 函數替換為如下所示的 HandleClick 類:

...
class HandleClick:
   def __init__(self, usrname='usr', password ='pswd', orcldb='127.0.0.1/XE'):
      self.dbconn = cx_Oracle.connect(usrname, password, orcldb)
   def __del__(self):
      self.dbconn.close()
   def processClick(self,guid,clks):
      self.dbconn.cursor().execute('''call count_clicks(:guid, :clks)''', {'guid':guid, 'clks':clks})

假設您將修訂保存在 oraclepersist_class.py 文件中,更新后的 dispatcher.psp 現在可能如下所示:

...
﹤%
import oraclepersist_class
import urllib
from mod_python import util
params = util.FieldStorage(req)
h = oraclepersist_class.HandleClick()
h.processClick(urllib.unquote_plus(params['guid'].value),  1)
psp.redirect(urllib.unquote_plus(params['url'].value))
%﹥
...

 

下面您創建 HandleClick 類的一個實例,然后調用它的 processClick 方法,正確傳遞參數,就像您之前所做的那樣。

在此處所討論的 HandleClick 類中,特別令人感興趣的是特殊類方法 methods __init__ 和 __del__ 的使用。與其他特殊方法一樣,您從不直接調用它們。相反,Python 隱式調用它們以響應在實例生命周期期間發生的某些事件。因此在創建實例時調用 __init__ 構造函數,在銷毀實例之前調用 __del__ 析構函數。

在上面的示例中,您在構造函數中連接到數據庫并在析構函數中關閉該連接。但在某些情況下,采用這些方法實現更多操作可能是非常令人感興趣的。例如,您可能希望在銷毀實例之前從析構函數中發出 SQL 語句。以下代碼片段將闡釋如何重新編寫 HandleClick 類,以便從析構函數中而不是從某個顯式調用的類方法中調用 count_clicks 存儲過程: 

...
  class HandleClick:
  def __init__(self, usrname='usr', password ='pswd', orcldb='127.0.0.1/XE'):
  self.dbconn = cx_Oracle.connect(usrname, password, orcldb)
  self.params ={}
  def __del__(self):
  self.dbconn.cursor().execute('''call count_clicks(:guid, :clks)''', self.params)
  self.dbconn.close()
  def addArticleClick(self,guid,clks):
  self.params['guid']=guid
  self.params['clks']=clks

 

正如您所見,更新的 HandleClick 類中不再有 processClick。相反,客戶端代碼應調用 addArticleClick,該函數用要傳遞給 count_clicks 存儲過程的參數填充該類的屬性 params dictionary,將從析構函數中調用 count_clicks 存儲過程。因此,現在您可以重新編寫嵌入在 dispatcher.psp 頁面中的 Python 代碼塊,如下所示:

...
﹤%
import oraclepersist_class
import urllib
from mod_python import util
params = util.FieldStorage(req)
h = oraclepersist_class.HandleClick()
h.addArticleClick(urllib.unquote_plus(params['guid'].value), 1)
del h
psp.redirect(urllib.unquote_plus(params['url'].value))
%﹥
...

注意,此處使用 del 語句取消包含綁定對 HandleClick 類的某個實例的引用的 h 變量。由于這是對該實例的唯一引用,因此之后 Python 將使用一種名為垃圾回收的機制隱式刪除該實例。刪除后,將自動觸發 __del__ 析構函數,執行 SQL 語句,然后關閉連接。

上面的示例極好地說明了采用 Python 開發面向對象的代碼時使用特殊方法可以獲取的優勢。在這個特殊示例中,客戶端代碼只負責為要針對數據庫發出的查詢設置參數,而 Python 隱式執行其余操作。

結論

正如您在本文中所學到的,開發一個可擴展的數據庫驅動的 Web 應用程序需要進行較良好的規劃。繼續構建應用程序組件和編寫代碼之前,您必須首先決定可以在數據庫中實現的應用程序邏輯的數量以及可以在前端層實現的操作。

設計文章示例時,將一些數據處理邏輯放到數據庫中,實現幾個 PL/SQL 存儲過程。在這里您學習了如何使用 Oracle XML DB 特性從網頁中獲取 XML 數據,然后從獲取的 XML 文檔中提取所需的信息。然后,構建一些 Python 代碼,用以編排存儲過程所執行的完整操作流。依次從構建的 PSP 頁面中調用這些 Python 代碼,以實現應用程序的前端層。因此,您獲得了相應的應用程序,該應用程序從網頁中獲取某些實時數據,并跟蹤用戶在您站點上的活動,將該信息存儲在數據庫中。在 Python 端,您看到了如何使用 Python 語言的內置工具獲取、保留以及操作結構化數據,這些工具包括:列表、字典和列表內涵。您還了解了在將應用程序邏輯和數據封裝到類中時如何利用 Python 的面向對象的特性。

【編輯推薦】

  1. Java應向Python學習對待缺陷的態度
  2. Ruby、Python不能威脅Java的13個理由
  3. Python異常處理體系簡介
責任編輯:book05 來源: IT168
相關推薦

2010-10-26 16:27:37

連接Oracle數據庫

2011-02-28 17:12:20

Oracle數據庫

2024-05-08 08:37:44

2010-05-04 11:58:38

Oracle數據庫

2011-05-26 10:30:12

Oracle數據庫約束

2015-08-21 12:59:38

Oracle數據庫

2011-03-10 13:24:26

2010-04-23 09:23:44

Oracle 數據庫

2011-03-16 08:54:45

Oracle數據庫索引

2010-05-04 14:57:27

Oracle數據庫

2011-05-19 13:25:14

Oracle數據庫

2010-10-26 16:07:45

連接oracle數據庫

2010-04-22 16:08:24

Oracle數據庫

2009-12-14 16:00:32

Ruby操作Oracl

2011-08-02 11:16:08

Oracle數據庫歸檔日志

2011-08-12 12:34:27

Oracle數據庫consistent

2011-08-16 13:17:29

2011-08-11 16:55:34

Oracle數據庫AWR

2010-04-14 15:14:11

Oracle數據庫

2010-06-17 12:59:07

Oracle
點贊
收藏

51CTO技術棧公眾號

久久伦理在线| 日本另类视频| 91亚洲国产成人精品一区二三| 欧美激情中文网| 亚洲 欧美 日韩在线| 国产传媒在线观看| 国产欧美精品区一区二区三区 | 黄色a级在线观看| 亚洲av少妇一区二区在线观看 | 伊人开心综合网| 国产一区二区高清视频| 最近日韩免费视频| 欧美精品一线| 国产一区二区欧美日韩| 97免费公开视频| 日韩免费va| 亚洲综合免费观看高清完整版在线 | 欧美精品18videosex性欧美| 国产三级av在线播放| 亚洲国产欧美在线观看| 在线精品视频小说1| 成年在线观看视频| av网站大全在线观看| 成人国产在线观看| 91九色国产视频| 中文字幕日韩免费| 1024成人| 欧美精品一区在线播放| 波多野结衣一二三四区| 欧美电影在线观看免费| 91精品啪在线观看国产60岁| 北条麻妃av高潮尖叫在线观看| 欧美xxxxhdvideosex| 国产精品另类一区| 欧美视频观看一区| 欧美一级在线免费观看| 国产一区二区视频在线播放| 国产精品久久久久久一区二区| 四虎永久在线精品| 欧美日本中文| 另类视频在线观看| 三级黄色免费观看| 久久一区二区三区电影| 国产亚洲精品久久久久久777| 网站免费在线观看| 精品久久ai电影| 亚洲精品一区二区三区99| 一级做a爱视频| 欧美一区二区三区婷婷| 91激情在线视频| 欧美性大战久久久久xxx| 精精国产xxxx视频在线中文版| 亚洲情趣在线观看| 国产高清免费在线| 国产黄大片在线观看画质优化| 中文字幕乱码一区二区免费| 欧美日韩一区二区三区免费| 男人久久精品| 久久久国产精华| 欧洲精品亚洲精品| 国产视频网站在线| 欧美国产丝袜视频| 亚洲综合欧美日韩| 欧美69xxx| 亚洲乱码中文字幕| 毛片在线视频观看| 91破解版在线观看| 欧美日韩中文字幕在线视频| 97超碰青青草| 在线成人视屏| 欧美久久高跟鞋激| 日本黄色www| 成人h动漫免费观看网站| 精品国产亚洲在线| 国产呦小j女精品视频| 少妇一区二区三区| 亚洲午夜小视频| a一级免费视频| 国产精品xvideos88| 国内精品久久久久久中文字幕| 日本熟妇乱子伦xxxx| 亚洲欧美日韩国产一区| 国产精品成av人在线视午夜片| 国产在线观看第一页| 精品一区二区三区蜜桃| 波多野结衣成人在线| 艳母动漫在线看| 欧美激情一区在线| 可以在线看黄的网站| 51漫画成人app入口| 日韩欧美有码在线| 色一情一区二区三区| av成人资源| 亚洲视频视频在线| 国产极品国产极品| 午夜在线播放视频欧美| 国产精自产拍久久久久久| 国产富婆一级全黄大片| www成人在线观看| 国产高清精品软男同| av电影在线地址| 欧美三级三级三级| 深夜视频在线观看| 精品国产91久久久久久浪潮蜜月| 久久综合久久美利坚合众国| 日韩在线视频免费播放| 精品一区二区三区的国产在线播放| 99re在线视频观看| 都市激情在线视频| 亚洲成av人片| 中文字幕中文在线| 台湾佬综合网| 欧美福利视频网站| 日本成人一级片| 成人深夜视频在线观看| 亚洲高清视频一区二区| 欧美久久天堂| 91精品国产免费| av网站免费在线看| 亚洲激情精品| 亚洲伊人久久大香线蕉av| 美国成人毛片| 亚洲第一主播视频| 亚洲免费成人在线视频| 久久不见久久见免费视频7| 欧美激情18p| 国产原创中文av| 国产欧美一二三区| 久久久999视频| 6080成人| 欧美成人三级视频网站| 亚洲熟妇无码久久精品| 91理论电影在线观看| 99热这里只有精品免费| 亚洲久草在线| 有码中文亚洲精品| 国产精品视频123| 成人激情免费电影网址| 加勒比海盗1在线观看免费国语版| 色婷婷综合久久久中字幕精品久久| 欧美va天堂va视频va在线| 艳妇荡乳欲伦69影片| 免费一级欧美片在线观看| 蜜桃av噜噜一区二区三| 国模精品视频| 亚洲成年人在线播放| 欧美又粗又大又长| 国产一区二区成人久久免费影院| 视频一区免费观看| 欧美影视资讯| 在线观看欧美成人| 亚洲视频一区在线播放| 中文字幕中文字幕中文字幕亚洲无线| 久久午夜夜伦鲁鲁一区二区| 亚洲人成精品久久久 | 日本一区二区三区四区五区六区| 国产资源一区| 日韩亚洲第一页| 91丨九色丨丰满| 亚洲视频一区在线| 亚洲av毛片在线观看| 亚洲一区色图| 99高清视频有精品视频| 人妖欧美1区| 亚洲第一页自拍| 日产精品久久久| 久久久久久久久久久久久夜| 欧美 日韩 国产一区| 久久综合亚洲| 国产欧美日韩精品丝袜高跟鞋| 久久精品视频免费看| 欧美一级日韩不卡播放免费| 男人与禽猛交狂配| 成人久久视频在线观看| 国产视频一视频二| 精品一区av| 亚洲综合成人婷婷小说| 99热99re6国产在线播放| 日韩激情av在线免费观看| 五月天婷婷导航| 国产精品三级av| 欧美专区第二页| 亚洲国产二区| 午夜精品美女久久久久av福利| 伊人久久大香| 午夜精品久久久久久久男人的天堂| 欧美视频免费一区二区三区| 欧美日韩免费观看一区三区| 日韩女优一区二区| 91丨porny丨户外露出| 国产又大又黄又粗又爽| 欧美在线91| 久久99九九| 色综合一区二区日本韩国亚洲| 日韩有码在线观看| 五月婷婷伊人网| 欧美日韩久久一区| 国产精品变态另类虐交| 国产欧美日韩视频一区二区| 91丨porny丨九色| 久久精品综合| 欧美激情亚洲天堂| 精品少妇av| 国产一区二区三区色淫影院 | 国产精品久久777777毛茸茸 | 草美女在线观看| 在线视频日韩精品| 手机看片国产1024| 欧美精三区欧美精三区| 国产成人在线播放视频| 自拍偷在线精品自拍偷无码专区| 中文字幕 日本| 韩国一区二区在线观看| 成人黄色片视频| 欧美三级不卡| 中文字幕一区二区中文字幕| 日韩电影不卡一区| 99精品国产高清一区二区| 国产69精品久久久久9999人| 久久免费精品视频| 欧洲美女少妇精品| 亚洲人成免费电影| 日韩一区二区三区在线观看视频| 欧美日韩视频一区二区| www.国产色| 亚洲成a人在线观看| 日本成人精品视频| 久久综合九色欧美综合狠狠| 香蕉视频免费网站| 国产美女视频一区| 无尽裸体动漫2d在线观看| 蜜桃久久av| 欧美日韩精品在线一区二区| 欧美喷水视频| 国产在线拍揄自揄拍无码| 精品日产免费二区日产免费二区| 免费看成人av| 欧美一区二区三区红桃小说| 粉嫩av一区二区三区免费观看 | 免费99视频| 精品自拍偷拍| 精品国产乱码一区二区三区四区| 日韩在线精品强乱中文字幕| 成人网在线免费观看| 免费视频观看成人| 成人午夜在线观看| 四虎精品在线观看| 成人两性免费视频| 粉嫩一区二区三区在线观看| 国产日韩精品视频| 四虎国产精品免费久久| 国产在线观看精品| 中文幕av一区二区三区佐山爱| 国产在线视频不卡| 国产日韩欧美中文在线| 91一区二区三区| 一区二区三区在线免费看| 99精品国产高清在线观看| 99ri日韩精品视频| 黄色一区三区| 杨幂一区二区三区免费看视频| 蜜桃传媒视频麻豆一区 | 肉大捧一出免费观看网站在线播放| 久久中文字幕av| 99re8这里只有精品| 欧美freesex交免费视频| 91视频 - 88av| 亚洲国产一区二区精品专区| 水蜜桃色314在线观看| 一本久道综合久久精品| 国产熟女高潮视频| 免费高清在线视频一区·| 色呦色呦色精品| 国产精品综合二区| 国产一卡二卡三卡四卡| 91久色porny| 日本猛少妇色xxxxx免费网站| 国产精品女主播av| 久久av高潮av无码av喷吹| 亚洲va欧美va人人爽| 销魂美女一区二区| 欧美久久久久久蜜桃| 亚洲成a人片77777精品| 日韩精品视频中文在线观看| 国产一级片在线播放| 精品国模在线视频| av资源中文在线天堂| 欧亚精品在线观看| 日韩成人综合网站| 国产精品一区二区三区在线观| 神马日本精品| 咪咪色在线视频| 99综合视频| 97超碰成人在线| 99久久99精品久久久久久| 亚洲天堂岛国片| 亚洲一区二区在线播放相泽| 久久久久久久久久久影院 | 熟妇人妻系列aⅴ无码专区友真希 熟妇人妻av无码一区二区三区 | 视色视频在线观看| 成人免费高清在线| 任我爽在线视频| 欧美日韩在线视频观看| 99在线观看免费| 在线日韩av观看| 国产伦理精品| 91中文在线观看| 精品国产一级毛片| 天天夜碰日日摸日日澡性色av| 久久av老司机精品网站导航| 免费成人蒂法网站| 亚洲免费电影在线| 中文字幕在线一| 亚洲欧美国产va在线影院| 手机av免费在线| 国产精品自在线| 精品一区二区三区的国产在线观看| 国产曰肥老太婆无遮挡| 久久se精品一区精品二区| 捆绑凌虐一区二区三区| 亚洲黄色录像片| 国产九色91回来了| 亚洲摸下面视频| 成人影院在线视频| 99精品国产高清在线观看| 久久福利综合| 成人免费视频久久| 日韩毛片中文字幕| 成人在线观看高清| 在线一区二区三区四区五区| 日韩一卡二卡在线| 欧美激情视频在线观看| 色综合久久久| 亚洲国产高清国产精品| 一区二区三区成人精品| 师生出轨h灌满了1v1| 亚洲欧美日韩综合aⅴ视频| 涩涩视频在线观看| 在线成人一区二区| 欧美日韩亚洲国产| 色女人综合av| 日本va欧美va欧美va精品| a级片在线观看| 欧美性极品xxxx娇小| 五月色婷婷综合| 性欧美视频videos6一9| 9l视频自拍九色9l视频成人| 日韩video| 粉嫩绯色av一区二区在线观看| 午夜剧场免费在线观看| 91精品国产综合久久香蕉麻豆| 日本www在线观看| 成人av番号网| 亚洲高清资源在线观看| 一区二区久久精品| 亚洲精品日日夜夜| 亚洲欧美激情国产综合久久久| 欧美大片在线影院| 国产精品115| 18岁网站在线观看| 国产亚洲va综合人人澡精品 | 国产精品毛片久久| gogogo高清免费观看在线视频| 国产精品久久久久久久久免费桃花| 中文在线字幕免费观| 久久中文字幕一区| 极品束缚调教一区二区网站| 色欲色香天天天综合网www| 99在线热播精品免费| 亚洲黄网在线观看| 最新69国产成人精品视频免费| 日韩欧美激情| www插插插无码免费视频网站| 成人污视频在线观看| 亚洲不卡视频在线观看| 在线观看久久久久久| 日韩精品一区二区三区中文字幕 | 一个人看的www视频在线免费观看| 久久精品美女| 久久成人免费网站| 国产成人精品亚洲男人的天堂| 亚洲美女av黄| 香蕉成人在线| 黄色片网址在线观看| 国产三级欧美三级| 精品国产乱码一区二区三| 韩国v欧美v日本v亚洲| 国产成人三级| 久久久久无码精品| 日韩欧美高清在线视频| 日本不卡在线| 久久久久欧美| 激情综合色综合久久| 国产成人在线免费观看视频| 国产亚洲精品久久久久久777| 日韩精品一区二区三区中文字幕| 欧美极品欧美精品欧美图片| 亚洲品质自拍视频网站| 精品推荐蜜桃传媒| 产国精品偷在线|