07-09面向過程與函數(shù)式

[TOC]

成都創(chuàng)新互聯(lián)公司是一家專注于網(wǎng)站設(shè)計制作、做網(wǎng)站與策劃設(shè)計,呂梁網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:呂梁等地區(qū)。呂梁做網(wǎng)站價格咨詢:18980820575

一 編程范式

? 很多初學(xué)者在了解了一門編程語言的基本語法和使用之后,面對一個’開發(fā)需求‘時仍然會覺得無從下手、沒有思路/套路,本節(jié)主題“編程范式”正是為了解決該問題,那到底什么是編程范式呢?

編程范式指的就是編程的套路,打個比方,如果把編程的過程比喻為練習(xí)武功,那編程范式指的就是武林中的各種流派,而在編程的世界里常見的流派有:面向過程、函數(shù)式、面向?qū)ο蟮?,本?jié)我們主要介紹前兩者。

? 在正式介紹前,我們需要強調(diào):“功夫的流派沒有高低之分,只有習(xí)武的人才有高低之分“,在編程世界里更是這樣,各種編程范式在不同的場景下都各有優(yōu)劣,誰好誰壞不能一概而論,下面就讓我們來一一解讀它們。

插圖:惡搞圖62
07-09 面向過程與函數(shù)式

二 面向過程

? ”面向過程“核心是“過程”二字,“過程”指的是解決問題的步驟,即先干什么再干什么......,基于面向過程開發(fā)程序就好比在設(shè)計一條流水線,是一種機械式的思維方式,這正好契合計算機的運行原理:任何程序的執(zhí)行最終都需要轉(zhuǎn)換成cpu的指令流水按過程調(diào)度執(zhí)行,即無論采用什么語言、無論依據(jù)何種編程范式設(shè)計出的程序,最終的執(zhí)行都是過程式的。

插圖:惡搞圖63
07-09 面向過程與函數(shù)式

? 詳細(xì)的,若程序一開始是要著手解決一個大的問題,按照過程式的思路就是把這個大的問題分解成很多個小問題或子過程去實現(xiàn),然后依次調(diào)用即可,這極大地降低了程序的復(fù)雜度。舉例如下:

? 寫一個數(shù)據(jù)遠程備份程序,分三步:本地數(shù)據(jù)打包,上傳至云服務(wù)器,檢測備份文件可用性

import os,time

# 一:基于本章所學(xué),我們可以用函數(shù)去實現(xiàn)這一個個的步驟
# 1、本地數(shù)據(jù)打包
def data_backup(folder):
    print("找到備份目錄: %s" %folder)
    print('正在備份...')
    zip_file='/tmp/backup_%s.zip' %time.strftime('%Y%m%d')
    print('備份成功,備份文件為: %s' %zip_file)
    return zip_file

# 2、上傳至云服務(wù)器
def cloud_upload(file):
    print("\nconnecting cloud storage center...")
    print("cloud storage connected")
    print("upload [%s] to cloud..." %file)
    link='https://www.xxx.com/bak/%s' %os.path.basename(file)
    print('close connection')
    return link

#3、檢測備份文件可用性
def data_backup_check(link):
    print("\n下載文件: %s , 驗證文件是否無損..." %link)

# 二:依次調(diào)用
# 步驟一:本地數(shù)據(jù)打包
zip_file = data_backup(r"/Users/egon/歐美100G高清無碼")

# 步驟二:上傳至云服務(wù)器
link=cloud_upload(zip_file)

# 步驟三:檢測備份文件的可用性
data_backup_check(link)

插圖:惡搞圖64
07-09 面向過程與函數(shù)式

面向過程總結(jié):

1、優(yōu)點

將復(fù)雜的問題流程化,進而簡單化

2、缺點

'''
程序的可擴展性極差,因為一套流水線或者流程就是用來解決一個問題,就好比生產(chǎn)汽水的流水線無法生產(chǎn)汽車一樣,即便是能,也得是大改,而且改一個組件,與其相關(guān)的組件可能都需要修改,比如我們修改了cloud_upload的邏輯,那么依賴其結(jié)果才能正常執(zhí)行的data_backup_check也需要修改,這就造成了連鎖反應(yīng),而且這一問題會隨著程序規(guī)模的增大而變得越發(fā)的糟糕。
'''

def cloud_upload(file): # 加上異常處理,在出現(xiàn)異常的情況下,沒有l(wèi)ink返回
    try:
        print("\nconnecting cloud storage center...")
        print("cloud storage connected")
        print("upload [%s] to cloud..." %file)
        link='https://www.xxx.com/bak/%s' %os.path.basename(file)
        print('close connection')
        return link
    except Exception:
        print('upload error')
    finally:
        print('close connection.....')

def data_backup_check(link): # 加上對參數(shù)link的判斷
    if link:
        print("\n下載文件: %s , 驗證文件是否無損..." %link)
    else:
        print('\n鏈接不存在')

3、應(yīng)用場景

面向過程的程序設(shè)計一般用于那些功能一旦實現(xiàn)之后就很少需要改變的場景, 如果你只是寫一些簡單的腳本,去做一些一次性任務(wù),用面向過程去實現(xiàn)是極好的,但如果你要處理的任務(wù)是復(fù)雜的,且需要不斷迭代和維護, 那還是用面向?qū)ο笞顬榉奖恪?/code>

插圖:惡搞圖65
07-09 面向過程與函數(shù)式

三 函數(shù)式

函數(shù)式編程并非用函數(shù)編程這么簡單,而是將計算機的運算視為數(shù)學(xué)意義上的運算,比起面向過程,函數(shù)式更加注重的是執(zhí)行結(jié)果而非執(zhí)行的過程,代表語言有:Haskell、Erlang。而python并不是一門函數(shù)式編程語言,但是仍為我們提供了很多函數(shù)式編程好的特性,如lambda,map,reduce,filter

插圖:惡搞圖66
07-09 面向過程與函數(shù)式

3.1 匿名函數(shù)與lambda

? 對比使用def關(guān)鍵字創(chuàng)建的是有名字的函數(shù),使用lambda關(guān)鍵字創(chuàng)建則是沒有名字的函數(shù),即匿名函數(shù),語法如下

lambda 參數(shù)1,參數(shù)2,...: expression

舉例

# 1、定義
lambda x,y,z:x+y+z

#等同于
def func(x,y,z):
    return x+y+z

# 2、調(diào)用
# 方式一:
res=(lambda x,y,z:x+y+z)(1,2,3)

# 方式二:
func=lambda x,y,z:x+y+z # “匿名”的本質(zhì)就是要沒有名字,所以此處為匿名函數(shù)指定名字是沒有意義的
res=func(1,2,3)

插圖:惡搞圖67
07-09 面向過程與函數(shù)式

匿名函數(shù)與有名函數(shù)有相同的作用域,但是匿名意味著引用計數(shù)為0,使用一次就釋放,所以匿名函數(shù)用于臨時使用一次的場景,匿名函數(shù)通常與其他函數(shù)配合使用,我們以下述字典為例來介紹它

salaries={
    'siry':3000,
    'tom':7000,
    'lili':10000,
    'jack':2000
}

要想取得薪水的最大值和最小值,我們可以使用內(nèi)置函數(shù)max和min(為了方便開發(fā),python解釋器已經(jīng)為我們定義好了一系列常用的功能,稱之為內(nèi)置的函數(shù),我們只需要拿來使用即可)

>>> max(salaries)
'tom'
>>> min(salaries)
'jack'

內(nèi)置max和min都支持迭代器協(xié)議,工作原理都是迭代字典,取得是字典的鍵,因而比較的是鍵的最大和最小值,而我們想要的是比較值的最大值與最小值,于是做出如下改動

# 函數(shù)max會迭代字典salaries,每取出一個“人名”就會當(dāng)做參數(shù)傳給指定的匿名函數(shù),然后將匿名函數(shù)的返回值當(dāng)做比較依據(jù),最終返回薪資最高的那個人的名字
>>> max(salaries,key=lambda k:salaries[k]) 
'lili'
# 原理同上
>>> min(salaries,key=lambda k:salaries[k])
'jack'

同理,我們直接對字典進行排序,默認(rèn)也是按照字典的鍵去排序的

>>> sorted(salaries)
['jack', 'lili', 'siry', 'tom']

插圖:惡搞圖68

07-09 面向過程與函數(shù)式

3.2 map、reduce、filter

函數(shù)map、reduce、filter都支持迭代器協(xié)議,用來處理可迭代對象,我們以一個可迭代對象array為例來介紹它們?nèi)齻€的用法

array=[1,2,3,4,5]

要求一:對array的每個元素做平方處理,可以使用map函數(shù)

map函數(shù)可以接收兩個參數(shù),一個是函數(shù),另外一個是可迭代對象,具體用法如下

>>> res=map(lambda x:x**2,array)
>>> res
<map object at 0x1033f45f8>
>>> 

解析:map會依次迭代array,得到的值依次傳給匿名函數(shù)(也可以是有名函數(shù)),而map函數(shù)得到的結(jié)果仍然是迭代器。

>>> list(res) #使用list可以依次迭代res,取得的值作為列表元素
[1, 4, 9, 16, 25]

插圖:惡搞圖69
07-09 面向過程與函數(shù)式

要求二:對array進行合并操作,比如求和運算,這就用到了reduce函數(shù)

reduce函數(shù)可以接收三個參數(shù),一個是函數(shù),第二個是可迭代對象,第三個是初始值

# reduce在python2中是內(nèi)置函數(shù),在python3中則被集成到模塊functools中,需要導(dǎo)入才能使用
>>> from functools import reduce 
>>> res=reduce(lambda x,y:x+y,array)
>>> res
15

解析:

1 沒有初始值,reduce函數(shù)會先迭代一次array得到的值作為初始值,作為第一個值數(shù)傳給x,然后繼續(xù)迭代一次array得到的值作為第二個值傳給y,運算的結(jié)果為3

2 將上一次reduce運算的結(jié)果作為第一個值傳給x,然后迭代一次array得到的結(jié)果作為第二個值傳給y,依次類推,知道迭代完array的所有元素,得到最終的結(jié)果15

也可以為reduce指定初始值

>>> res=reduce(lambda x,y:x+y,array,100)?>>> res
115

要求三:對array進行過濾操作,這就用到了filter函數(shù),比如過濾出大于3的元素

>>> res=filter(lambda x:x>3,array)

解析:filter函數(shù)會依次迭代array,得到的值依次傳給匿名函數(shù),如果匿名函數(shù)的返回值為真,則過濾出該元素,而filter函數(shù)得到的結(jié)果仍然是迭代器。

>>> list(res) 
[4, 5]

提示:我們介紹map、filter、reduce只是為了帶大家了解函數(shù)式編程的大致思想,在實際開發(fā)中,我們完全可以用列表生成式或者生成器表達式來實現(xiàn)三者的功能。

插圖:惡搞圖70
07-09 面向過程與函數(shù)式

分享文章:07-09面向過程與函數(shù)式
網(wǎng)頁地址:http://muchs.cn/article34/phocse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、面包屑導(dǎo)航全網(wǎng)營銷推廣、網(wǎng)站導(dǎo)航、做網(wǎng)站服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)