SQL Server 向暫時表拔出數據示例。本站提示廣大學習愛好者:(SQL Server 向暫時表拔出數據示例)文章只能為提供參考,不一定能成為您想要的結果。以下是SQL Server 向暫時表拔出數據示例正文
簡略生成器有很多長處。生成器除可以或許用更天然的辦法表達一類成績的流程以外,還極年夜地改良了很多效力缺乏的地方。在 Python 中,函數挪用價值不菲;除其它身分外,還要花一段時光處理函數參數列表(除其它的工作外,還要剖析地位參數和缺省參數)。初始化框架對象還要采用一些樹立步調(據 Tim Peters 在 comp.lang.python 上所說,有 100 多行 C 說話法式;我本身還沒檢討 Python 源代碼呢)。與此相反,恢復一個生成器就相當省力;參數曾經解析完了,並且框架對象正“無所事事地”期待恢復(簡直不須要額定的初始化)。固然,假如速度是最主要的,您不該該應用字節碼已編譯過的靜態說話;但即便在速度不是重要斟酌身分的情形下,快點總比慢點好。
回想狀況機
在“心愛的 Python”後面的另外一篇文章中,我引見了StateMachine 類 ,給定的機械須要若干狀況處置法式,它就許可用戶添加若干狀況處置法式。在模子中,將一個或多個狀況界說為終態(end state),僅將一個狀況界說為初始狀況(start state)(挪用類辦法對此停止設置裝備擺設)。每一個處置法式都有某種必須的構造;處置法式將履行一系列操作,然後過一會兒,它帶著一個標志前往到 StateMachine.run() 辦法中的輪回內,該標志指出了想獲得的下一個狀況。異樣,用 cargo 變量許可一個狀況把一些(未處置的)信息傳遞給下一個狀況。
我引見的 StateMachine 類的典范用處是以一個有狀況的方法應用輸出。例如,我所用的一個文本處置對象(Txt2Html)從一個文件中讀取數行內容;根據每行所屬的種別,須要以特別的方法對其停止處置。但是,您常常須要看看後面幾行供給的高低文來肯定以後行屬於哪一個種別(和應當如何處置它)。構建在 StateMachine 類上的這個進程的完成可以界說一個 A 處置法式,該處置法式讀取幾行,然後以相似 A 的方法處置這些行。不久,知足了一個前提,如許下一批的幾行內容就應當由 B 處置法式來處置了。 A 把掌握傳遞回 .run() 輪回,同時指導切換到 B 狀況 ― 和任何 A 不克不及准確處置的、 B 應當在浏覽額定的幾行之前處置的額定的行。最初,某個處置法式將它的掌握傳遞給某個被指定為終態的狀況,處置停滯(halt)。
關於後面一部門中的詳細代碼示例,我應用了一個簡化過的運用法式。我處置由迭代函數發生的數字流,而不是處置多行內容。每一個狀況處置法式僅打印那些在希冀的數字規模內的數字(和關於有用狀況的一些新聞)。當數字流中的一個數字傳到一個分歧的規模內,另外一個分歧的處置法式就會接收“處置”。關於這一部門,我們將看看另外一種用生成器完成雷同數字流處置的方法(有一些額定的技能和功效)。然則,一個更龐雜的生成器示例有能夠對更象上一段中提到的輸出流停止處置。我們再來看看前一個狀況機刪減過代碼的版本:
清單 1. statemachine_test.py
from statemachine import StateMachine def ones_counter(val): print "ONES State: ", while 1: if val <= 0 or val >= 30: newState = "Out_of_Range" ; break elif 20 <= val < 30: newState = "TWENTIES"; break elif 10 <= val < 20: newState = "TENS"; break else: print " @ %2.1f+" % val, val = math_func(val) print " >>" return (newState, val) # ... other handlers ... def math_func(n): from math import sin return abs(sin(n))*31 if __name__== "__main__": m = StateMachine() m.add_state("ONES", ones_counter) m.add_state("TENS", tens_counter) m.add_state("TWENTIES", twenties_counter) m.add_state("OUT_OF_RANGE", None, end_state=1) m.set_start("ONES") m.run(1)
讀者假如接上去對導入的 StateMachine 類和它的辦法若何任務感興致,應當看看後面的文章。
應用生成器
基於生成器的狀況機的完全版本比我更情願在本專欄中引見的代碼樣本略長。不外,上面的代碼樣本是完全的運用法式,並且不須要導入零丁的 statemachine 模塊以供給支撐。總的來講,這個版本比基於類的誰人版本要短一些(我們將看到它有一些特殊的地方,並且還異常壯大)。
清單 2. stategen_test.py
from __future__ import generators import sys def math_gen(n): # Iterative function becomes a generator from math import sin while 1: yield n n = abs(sin(n))*31 # Jump targets not state-sensitive, only to simplify example def jump_to(val): if 0 <= val < 10: return 'ONES' elif 10 <= val < 20: return 'TENS' elif 20 <= val < 30: return 'TWENTIES' else: return 'OUT_OF_RANGE' def get_ones(iter): global cargo while 1: print "\nONES State: ", while jump_to(cargo)=='ONES': print "@ %2.1f " % cargo, cargo = iter.next() yield (jump_to(cargo), cargo) def get_tens(iter): global cargo while 1: print "\nTENS State: ", while jump_to(cargo)=='TENS': print "#%2.1f " % cargo, cargo = iter.next() yield (jump_to(cargo), cargo) def get_twenties(iter): global cargo while 1: print "\nTWENTIES State: ", while jump_to(cargo)=='TWENTIES': print "*%2.1f " % cargo, cargo = iter.next() yield (jump_to(cargo), cargo) def exit(iter): jump = raw_input('\n\n[co-routine for jump?] ').upper() print "...Jumping into middle of", jump yield (jump, iter.next()) print "\nExiting from exit()..." sys.exit() def scheduler(gendct, start): global cargo coroutine = start while 1: (coroutine, cargo) = gendct[coroutine].next() if __name__ == "__main__": num_stream = math_gen(1) cargo = num_stream.next() gendct = {'ONES' : get_ones(num_stream), 'TENS' : get_tens(num_stream), 'TWENTIES' : get_twenties(num_stream), 'OUT_OF_RANGE': exit(num_stream) } scheduler(gendct, jump_to(cargo))
關於基於生成器的狀況機,要研討的處所還許多。第一點在很年夜水平上是外面性的。我們支配 stategen_test.py 只能應用函數,不克不及應用類(至多按我的意思,生成器更有一種函數編程的感到而非面向對象編程(OOP)的感到)。然則,假如願望的話,您可以很輕易地把雷同的通用模子包裝到一個或多個類中。
我們的樣本中的主函數是 scheduler() ,它完整是普通性的(然則比後面的形式中的 StateMachine 要短很多)。函數 scheduler() 請求生成器-迭代器對象字典(“實例化的”生成器)作為參數。給每一個生成器取的字符串稱號可所以您所願望的隨意率性稱號 ― 生成器工場函數的字面稱號是一個不言而喻的選擇,然則我在示例中應用年夜寫的症結字稱號。 scheduler() 函數還接收“初始狀況”作為參數,但假如您願望的話,或許可以主動選擇一個缺省值。
每一個“已調劑的”生成器遵守一些簡略的通例。每一個生成器運轉一段時光,然後發生一對值,包括希冀的跳轉和某個“cargo” ― 就像用後面的模子一樣。沒有生成器被明白地標志為“終態”。相反,我們許可各個生成器選擇發生毛病來停止 scheduler() 。特別情形下,假如生成器“分開”終態或許達到一個 return 狀況,生成器將發生 StopIteration 異常。假如須要的話,您可以捕捉這個異常(或許是一個分歧的異常)。在我們的例子中,我們應用 sys.exit() 來終止運用法式,在 exit() 生成器中會碰到這個 sys.exit()。
要留意關於代碼的兩個小成績。下面的樣本應用一個更簡練的輪回生成器-迭代器,而不是應用迭代函數來生成我們的數字序列。生成器僅跟著每一個後續的挪用收回一個(無限的/不肯定的)數字流,而不是持續前往“最初的值”。這是一個固然小但卻好用的生成器樣本。並且,下面把“狀況轉換”隔離在了一個零丁的函數中。在現實法式中,狀況改變跳轉更是高低文相干的,並且能夠要在現實的生成器體內決議。該門路簡化了樣本。雖然能夠用途不年夜,然則您權且聽聽,我們完整可以經由過程一個函數工場發生生成器函數從而進一步簡化;然則普通情形每一個生成器都不會與其它生成器類似到足以使這類辦法實在可行。
協同法式和半協同法式
仔細的讀者能夠留意到了,現實上我們不知不覺地進入了一種比最後所注解的要有效很多的流掌握構造。在樣本代碼中,不只僅只是有了狀況機。現實上,下面的形式是一個很有用的協同法式通用的體系。年夜多半讀者在此也許會須要一些配景常識。
協同法式是法式功效的聚集,它許可隨意率性地分支到其它的掌握高低文中 和從分支點隨意率性恢復流。我們在年夜多半編程說話中所熟習的子例程是通用協同法式的一種極其無限的分支情形。子例程僅從頂真個一個固定點進入而且只加入一次(它不克不及被恢復)。子例程還老是把傳播送回它的挪用者處。實質上,每一個協同法式代表一個可挪用的延續 ― 雖然添加一個新的單詞其實不必定能向不曉得這個單詞的人說明它的意思。Randall HydeAn 的 The Art of Assembly中的“Cocall Sequence Between Two Processes”插圖關於說明協同法式年夜有贊助。 參考材料上有到此圖的鏈接。參考材料中還有到 Hyde 的綜合評論辯論的鏈接,該評論辯論相當不錯。
不論算不算負面影響,您照樣會留意到,在很多說話中污名昭著的 goto 語句也許可隨意率性分支,然則在一個不太構造化的高低文中,它能招致“通心粉 代碼”。
Python 2.2+ 的生成器向協同法式邁進了一年夜步。這一年夜步是指,生成器 ― 和函數/子例程分歧 ― 是可恢復的,而且可以在多個挪用以後獲得值。但是,Python 生成器只不外是 Donald Knuth 所描寫的“半協同法式”。生成器是可恢復的,而且可以在別處罰支掌握 ― 然則它只能分支掌握回到直接挪用它的挪用者處。確實的說,生成器高低文(和任何高低文一樣)可以本身挪用其它生成器或函數 ― 乃至可以它本身停止遞歸挪用 ― 然則每一個終究的前往必需經過前往高低文的線性條理構造傳遞。Python 生成器不斟酌“臨盆者”和“花費者”的罕見協同法式用法(可以隨便從對方的中央地位持續)。
榮幸的是,用 Python 生成器模擬裝備齊備的的協同法式相當輕易。簡略的訣竅就是和下面樣本代碼中生成器非常相似的 scheduler() 函數。現實上,我們所提出的狀況機自己就是一個罕見很多的協同法式框架形式。順應這類形式能戰勝 Python 生成器中仍存在的小缺點(讓粗枝大葉的法式員也能施展出通心粉代碼的全體力氣)。
操作中的 Stategen
要想精確懂得 stategen_test.py 中產生了甚麼,最簡略的方法就是運轉它:
清單 3. 運轉 STATEGEN(手工跳轉掌握)
% python stategen_test.py ONES State: @ 1.0 TWENTIES State: *26.1 *25.3 ONES State: @ 4.2 TWENTIES State: *26.4 *29.5 *28.8 TENS State: #15.2 #16.3 #16.0 ONES State: @ 9.5 @ 3.8 TENS State: #18.2 #17.9 TWENTIES State: *24.4 TENS State: #19.6 TWENTIES State: *21.4 TENS State: #16.1 #12.3 ONES State: @ 9.2 @ 6.5 @ 5.7 TENS State: #16.7 TWENTIES State: *26.4 *30.0 [co-routine for jump?] twenties ...Jumping into middle of TWENTIES TWENTIES State: TENS State: #19.9 TWENTIES State: *26.4 *29.4 *27.5 *22.7 TENS State: #19.9 TWENTIES State: *26.2 *26.8 Exiting from exit()...
這個輸入和後面的 statemachine_test.py 中的輸入根本上是完整雷同的。成果中的每行分離表現在特定的處置法式或生成器中應用的流;外行的開首聲清楚明了流高低文。然則,每當另外一個協同法式分支轉到生成器內時,生成器版本 恢復履行(在一個輪回內),而不只僅是再次 挪用處置法式函數。假定一切的 get_*() 協同法式體都包括在無窮輪回中,這點差別就不那末顯著了。
要懂得 stategen_test.py 中的實質差別,看看 exit() 生成器中產生了甚麼。第一次挪用生成器-迭代器時,從用戶處搜集一個跳轉目的(這是實際中的運用中有能夠應用的事宜驅動分支決議計劃的一種簡略情形)。但是,當再次挪用 exit() 時,它位於生成器的一個稍後的流高低文中 ― 顯示加入新聞,並挪用 sys.exit() 。交互感化樣本中的用戶完整可以直接跳轉到“out_of_range”,不消轉到另外一個“處置法式”就加入(然則它 將履行一個到這個雷同生成器內的遞歸跳轉)。
停止語
我在引見中說過,我希冀狀況機版本的協同法式運轉速度年夜年夜跨越後面引見的帶回調解理法式的類(class-with-callback-handler)"版本的速度。恢回生成器-迭代器效力要高很多。特定的示例如斯簡略,簡直缺乏以作為評判尺度,然則我迎接讀者對詳細成果停止反應。
但不論我引見的“協同法式形式”在速度方面能夠獲得甚麼樣的停頓,在它完成的驚人的通用流掌握眼前都邑相形見绌。comp.lang.python 消息組上的很多讀者都曾訊問過 Python 的重生成器有多通用。我想,我所描寫的框架的可用性作了答復:“和您想要的一樣!”關於年夜多半和 Python 有關的工作,對某些工作 編程平日比 懂得它們要簡略很多。嘗嘗我的形式;我想您會發明它很有效。