• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    可愛的 Python:創建聲明性迷你語言

    發布: 2007-7-04 20:06 | 作者: admin | 來源:  網友評論 | 查看: 17次 | 進入軟件測試論壇討論

    領測軟件測試網   Python 的面向對象和透明自省功能使您可以輕松地創建用于編程任務的聲明性迷你語言。在本專欄文章中,David 并未仔細研究如何使用 Python 來解釋或翻譯其它的專門語言(盡管可以做得到),而是研究如何將 Python 代碼本身有效地限定在一組聲明性元素中。他將向您說明開發人員如何能使用聲明技術來簡練清晰地陳述應用程序的要求,而讓“幕后的”框架來完成繁重的工作。
      
      大多數程序員考慮編程時,他們都要設想用于編寫應用程序的命令式樣式和技術。最受歡迎的通用編程語言(包括 Python 和其它面向對象的語言)在樣式上絕大多數都是命令式的。另一方面,也有許多編程語言是聲明性樣式,包括函數語言和邏輯語言,還包括通用語言和專用語言。
      
      讓我們列出幾個屬于各個種類的語言。許多讀者已經使用過這些工具中的許多工具,但不見得考慮過它們之間的種類差別。Python、C、C++、Java、Perl、Ruby、Smalltalk、Fortran、Basic 和 xBase 都是簡單的命令式編程語言。其中,一些是面向對象的,但那只是組織代碼和數據的問題,而非基本編程樣式的問題。使用這些語言,您命令程序執行指令序列:把某些數據放入(put)變量中;從變量中獲。╢etch)數據;循環(loop)一個指令塊直到(until)滿足了某些條件;如果(if)某個命題為 true,那么就進行某些操作。所有這些語言的一個妙處在于:便于用日常生活中熟悉的比喻來考慮它們。日常生活都是由做事、選擇、再做另一件事所組成的,期間或許會使用一些工具?梢院唵蔚貙⑦\行程序的計算機想象成廚師、瓦匠或汽車司機。
      
      諸如 Prolog、Mercury、SQL、XSLT 這樣的語言、EBNF 語法和各種格式的真正配置文件,都聲明某事是這種情況,或者應用了某些約束。函數語言(比如 Haskell、ML、Dylan、Ocaml 和 Scheme)與此相似,但是它們更加強調陳述編程對象(遞歸、列表,等等)之間的內部(函數)關系。我們的日常生活(至少在敘事質量方面)沒有提供對這些語言的編程構造的直接模擬。然而,對于那些可以用這些語言進行描述的問題來說,聲明性描述遠遠比命令式解決方案來得簡明且不易出錯。例如,請研究下面這個線性方程組:
      
      清單 1. 線性方程式系統樣本
      10x + 5y - 7z + 1 = 0
      17x + 5y - 10z + 3 = 0
      5x - 4y + 3z - 6 = 0
      
      這是個相當漂亮的說明對象(x、y 和 z)之間幾個關系的簡單表達式。在現實生活中您可能會用不同的方式求出這些答案,但是實際上用筆和紙“求解 x”很煩,而且容易出錯。從調試角度來講,用 Python 編寫求解步驟或許會更糟糕。
      
      Prolog 是與邏輯或數學關系密切的語言。使用這種語言,您只要編寫您知道是正確的語句,然后讓應用程序為您得出結果。語句不是按照特定的順序構成的(和線性方程式一樣,沒有順序),而且您(程序員或用戶)并不知道得出的結果都采用了哪些步驟。例如:
      
      清單 2. family.pro Prolog 樣本
      /* Adapted from sample at:
      <http://www.engin.umd.umich.edu/CIS/course.des/cis479/prolog/>
      This app can answer questions about sisterhood & love, e.g.:
      # Is alice a sister of harry?
      ?-sisterof( alice, harry )
      # Which of alice' sisters love wine?
      ?-sisterof( X, alice ), love( X, wine)
      */
      sisterof( X, Y ) :- parents( X, M, F ),
      female( X ),
      parents( Y, M, F ).
      parents( edward, victoria, albert ).
      parents( harry, victoria, albert ).
      parents( alice, victoria, albert ).
      female( alice ).
      loves( harry, wine ).
      loves( alice, wine ).
      
      它和 EBNF(擴展巴科斯范式,Extended Backus-Naur Form)語法聲明并不完全一樣,但是實質相似。您可以編寫一些下面這樣的聲明:
      
      清單 3. EBNF 樣本
      word    := alphanums, (wordpunct, alphanums)*, contraction?
      alphanums  := [a-zA-Z0-9]+
      wordpunct  := [-_]
      contraction := "'", ("clock"/"d"/"ll"/"m"/"re"/"s"/"t"/"ve")
      
      如果您遇到一個單詞而想要表述其看上去可能會是什么,而實際上又不想給出如何識別它的序列指令,上面便是個簡練的方法。正則表達式與此相似(并且事實上它能夠滿足這種特定語法產品的需要)。
      
      還有另一個聲明性示例,請研究描述有效 XML 文檔方言的文檔類型聲明:
      
      清單 4. XML 文檔類型聲明
      <!ELEMENT dissertation (chapter+)>
      <!ELEMENT chapter (title, paragraph+)>
      <!ELEMENT title (#PCDATA)>
      <!ELEMENT paragraph (#PCDATA | figure)+>
      <!ELEMENT figure EMPTY>
      
      和其它示例一樣,DTD 語言不包含任何有關如何識別或創建有效 XML 文檔的指令。它只描述了如果文檔存在,那它會是怎么樣的。聲明性語言采用虛擬語氣。
      
      Python 作為解釋器 vs Python 作為環境
      Python 庫可以通過兩種截然不同的方式中的一種來利用聲明性語言;蛟S更為常用的技術是將非 Python 聲明性語言作為數據來解析和處理。應用程序或庫可以讀入外部來源(或者是內部定義的但只用作“blob”的字符串),然后指出一組要執行的命令式步驟,這些步驟在某種形式上與那些外部聲明是一致的。本質上,這些類型的庫是“數據驅動的”系統;聲明性語言和 Python 應用程序執行或利用其聲明的操作之間有著概念和范疇差別。事實上,相當普遍的一點是,處理那些相同聲明的庫也被用來實現其它編程語言。
      
      上面給出的所有示例都屬于第一種技術。庫 PyLog 是 Prolog 系統的 Python 實現。它讀取像樣本那樣的 Prolog 數據文件,然后創建 Python 對象來對 Prolog 聲明建模。EBNF 樣本使用專門變體 SimpleParse,這是一個 Python 庫,它將這些聲明轉換成可以被 mx.TextTools 所使用的狀態表。mx.TextTools 自身是 Python 的擴展庫,它使用底層 C 引擎來運行存儲在 Python 數據結構中的代碼,但與 Python 本質上幾乎沒什么關系。對于這些任務而言,Python 是極佳的粘合劑,但是粘合在一起的語言與 Python 差別很大。而且,大多數 Prolog 實現都不是用 Python 編寫的,這和大多數 EBNF 解析器一樣。
      
      DTD 類似于其它示例。如果您使用象 xmlproc 這樣的驗證解析器,您可以利用 DTD 來驗證 XML 文檔的方言。但是 DTD 的語言并不是 Python 式的,xmlproc 只將它用作需要解析的數據。而且,已經用許多編程語言編寫過 XML 驗證解析器。XSLT 轉換與此相似,也不是特定于 Python 的,而且像 ft.4xslt 這樣的模塊只將 Python 用作“粘合劑”。
      
      雖然上面的方法和上面所提到的工具(我一直都在使用)都沒什么不對,但如果 Python 本身是聲明性語言的話,那么它可能會更精妙,而且某些方面會表達得更清晰。如果沒有其它因素的話,有助于此的庫不會使程序員在編寫一個應用程序時考慮是否采用兩種(或更多)語言。有時,依靠 Python 的自省能力來實現“本機”聲明,既簡單又管用。
      
      自省的魔力
      解析器 Spark 和 PLY 讓用戶用 Python 來聲明 Python 值,然后使用某些魔法來讓 Python 運行時環境進行解析配置。例如,讓我們研究一下與前面 SimpleParse 語法等價的 PLY 語法。Spark 類似于下面這個示例:
      
      清單 5. PLY 樣本
      tokens = ('ALPHANUMS','WORDPUNCT','CONTRACTION','WHITSPACE')
      t_ALPHANUMS = r"[a-zA-Z0-0]+"
      t_WORDPUNCT = r"[-_]"
      t_CONTRACTION = r"'(clock|d|ll|m|re|s|t|ve)"
      def t_WHITESPACE(t):
      r"\s+"
      t.value = " "
      return t
      import lex
      lex.lex()
      lex.input(sometext)
      while 1:
      t = lex.token()
      if not t: break
      
      我已經在我即將出版的書籍 Text Processing in Python 中編寫了有關 PLY 的內容,并且在本專欄文章中編寫了有關 Spark 的內容(請參閱參考資料以獲取相應鏈接)。不必深入了解庫的詳細信息,這里您應當注意的是:正是 Python 綁定本身配置了解析(在這個示例中實際是詞法分析/標記化)。PLY 模塊在 Python 環境中運行以作用于這些模式聲明,因此就正好非常了解該環境。
      
      PLY 如何得知它自己做什么,這涉及到一些非常奇異的 Python 編程。起初,中級程序員會發現可以查明 globals() 和 locals() 字典的內容。如果聲明樣式略有差異的話就好了。例如,假想代碼更類似于這樣:
      
      清單 6. 使用導入的模塊名稱空間
      import basic_lex as _
      _.tokens = ('ALPHANUMS','WORDPUNCT','CONTRACTION')
      _.ALPHANUMS = r"[a-zA-Z0-0]+"
      _.WORDPUNCT = r"[-_]"
      _.CONTRACTION = r"'(clock|d|ll|m|re|s|t|ve)"
      _.lex()
      
      這種樣式的聲明性并不差,而且可以假設 basic_lex 模塊包含類似下面這樣的簡單內容:
      
      清單 7. basic_lex.py
      def lex():
      for t in tokens:
      print t, '=', globals()[t]
      
      這會產生:
      
      % python basic_app.py
      ALPHANUMS = [a-zA-Z0-0]+
      WORDPUNCT = [-_]
      CONTRACTION = '(clock|d|ll|m|re|s|t|ve)
      
      PLY 設法使用堆棧幀信息插入了導入模塊的名稱空間。例如:
      
      清單 8. magic_lex.py
      import sys
      try: raise RuntimeError
      except RuntimeError:
      e,b,t = sys.exc_info()

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>