激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python函數式編程實例詳解

Python函數式編程實例詳解

2020-04-19 10:55theVicTory Python

這篇文章主要介紹了Python函數式編程,結合實例形式詳細分析了Python函數式編程高階函數、匿名函數、閉包及函數裝飾器等相關概念、原理與使用技巧,需要的朋友可以參考下

本文實例講述了Python函數式編程。分享給大家供大家參考,具體如下:

函數式編程就是一種抽象程度很高的編程范式,從計算機硬件->匯編語言->C語言->Python抽象程度越高、越貼近于計算,但執行效率也越低。純粹的函數式編程語言編寫的函數沒有變量,因此,任意一個函數,只要輸入是確定的,輸出就是確定的,這種純函數我們稱之為沒有副作用。而允許使用變量的程序設計語言,由于函數內部的變量狀態不確定,同樣的輸入,可能得到不同的輸出,因此,這種函數是有副作用的。函數式編程的一個特點就是,允許把函數本身作為參數傳入另一個函數,還允許返回一個函數!

Python對函數式編程提供部分支持,支持高階函數(函數可以作為變量傳入),支持閉包(返回一個函數),有限地支持匿名函數。由于Python允許使用變量,因此,Python不是純函數式編程語言。

1、高階函數

 

即可以通過變量名指向函數,函數通過變量名作為參數傳給另一個函數,并通過變量名來使用。例如下面將開方函數math.sqrt作為參數傳遞給變量f,變量名f就指向了函數math.sqrt,再通過變量f使用該函數給x、y開方。

?
1
2
3
4
5
import math
def add(x, y, f):
  return f(x) + f(y) # 函數作為參數傳遞給f來調用
res = add(25, 9, math.sqrt)
print(res)

map函數接收一個函數 f 和一個 list,并把函數 f 依次作用在 list 的每個元素上,得到一個iterators并返回。

?
1
2
3
4
def format_name(s):
  return s[0].upper()+s[1:].lower()  #將列表的每個元素首字母大寫,其他小寫
print(list(map(format_name, ['adam', 'LISA', 'barT'])))
#輸出:['Adam', 'Lisa', 'Bart']

filter()根據判斷函數f的結果自動過濾掉不符合條件的元素,以iterators返回剩下的元素

?
1
2
3
4
def is_odd(x):
  return x % 2 == 1 # 過濾函數,x為奇返回True
f_res = filter(is_odd, [1, 4, 6, 7, 9, 12, 17])
print(list(f_res))  # 輸出過濾后的結果list:1 7 9 17

sorted()函數用于對可迭代的對象進行排序,參數key=指定排序的關鍵字,這里可以借助functools.cmp_to_keys()將比較方法映射為自定義的方法。例如實現了降序排列,比較函數cmp返回值 -1 代表a 應該排在 b 的前面,如果a排在b 的后面返回 1。如果 a、b相等返回 0。

?
1
2
3
4
5
6
7
8
9
import functools
def cmp(a, b):
  if b < a:
    return -1
  if a < b:
    return 1
  return 0
a = [1, 2, 5, 4]
print(sorted(a, key=functools.cmp_to_key(cmp)))

2、匿名函數和閉包

 

有時函數簡單到只有一個表達式時,為了簡化代碼可以使用匿名函數來代替,匿名函數一般形式為lambda 參數:返回表達式,例如lambda x:x*x,就是傳入x參數并返回x的平方。例如在使用map()函數時需要傳入一個函數用于list的元素,此時可以使用匿名函數作為參數

?
1
2
3
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]
res = map(lambda x: x * x, lst)  # 將匿名函數作用于lst
print(list(res))

函數的閉包(Closure)是指內層函數引用了外層函數的變量,然后將內層函數像變量一樣返回的情況。例如函數calc_prod()接收一個list,在其內部定義一個函數multiply,計算list元素的乘積并將multiply返回。用f接收calc_prod()的返回函數,并在之后調用該函數

?
1
2
3
4
5
6
7
8
9
def calc_prod(lst):
  def multiply():
    res=1
    for i in lst:
      res=res*i
    return res
  return multiply  # 將函數返回
f = calc_prod([1, 2, 3, 4])  # 接收返回函數
print(f())  # 調用返回函數

注意在函數閉包時要確保引用的局部變量在函數返回后不能變。例如下面的例子,當count()函數返回3個函數時,由于f1、f2、f3并沒有被調用,所以并未計算 i*i。當 f1 被調用時,這3個函數所引用的變量 i 的值已經變成了3,所以此時使用的變量i的值已經發生了改變,三個函數的輸出都是9。

?
1
2
3
4
5
6
7
8
9
10
def count():
  fs = []
  for i in range(1, 4):
    def f():
      print(i)  # 函數f1()調用時i已經變為3
      return i*i
    fs.append(f)
  return fs
f1, f2, f3 = count()
print(f1())      # 輸出9而不是1

3、函數裝飾器

 

函數裝飾器是指在原有函數的基礎上對函數作修改和裝飾操作。其基本思想是,既然函數可以像變量一樣作為參數傳入并且返回,那么我們可以將原來的函數傳入裝飾器函數,然后增加我們需要的操作,之后在將原函數返回出來。

例如下面定義了一個裝飾器log用于打印函數名稱,原函數作為參數f傳入。在裝飾器中定義新的函數fn,其中參數列*args和**kw代表自適應參數個數,防止不同參數個數的函數在使用裝飾器時不匹配。在新函數fn中輸出原函數的名稱,之后將原函數原封不動地調用一遍并返回出去。最后返回新函數。

在使用裝飾器時,只需要在函數的定義前加一行@裝飾器名

?
1
2
3
4
5
6
7
8
9
def log(f): # 定義裝飾器log
  def fn(*args, **kw): # 定義新函數
    print('函數名: ' + f.__name__)  # 打印函數名
    return f(*args, **kw) # 在新函數中調用原函數并返回結果
  return fn # 返回新函數
@log # 為函數add添加裝飾器
def add(x, y):
  return x + y
print(add(1, 2))

如果希望給裝飾器傳入一個參數,則需要定義三重嵌套的函數,在最外層增加一層函數用于接收參數。例如希望在打印函數名之前輸出傳入的參數“DEBUG”

?
1
2
3
4
5
6
7
8
9
10
11
def log(prefix):
  def log_decorator(f):
    def wrapper(*args, **kw):
      print '[%s] %s()...' % (prefix, f.__name__)
      return f(*args, **kw)
    return wrapper
  return log_decorator
@log('DEBUG'# 為裝飾器傳入參數
def test():
  pass
test()

由于裝飾器實際上是創建了新的函數fn并替代了原函數,所以原函數的相關信息例如函數名會被覆蓋,可以用@functools.wraps(f)來復制原函數的信息以保留下來。

?
1
2
3
4
5
6
7
import functools
def log(f):
  @functools.wraps(f)
  def fn(*args, **kw):
    print 'call...'
    return f(*args, **kw)
  return fn

偏函數可以為函數填上一個固定的參數值,從而生成一個新的函數。例如原函數add需要兩個參數x、y,通過指定y=1得到偏函數add1,這個函數只需要輸入一個參數x,從而計算x+1的值。

?
1
2
3
4
5
import functools
def add(x, y):
  return x + y
add1 = functools.partial(add, y=1)
print(add2(3))  # 輸出結果為4

希望本文所述對大家Python程序設計有所幫助。

原文鏈接:https://blog.csdn.net/theVicTory/article/details/95070465

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 日韩电影一区二区三区 | 欧美黑大粗硬毛片视频 | 亚洲精品欧美二区三区中文字幕 | 日韩色视频在线观看 | 久久久久久久亚洲视频 | 国产精品一区二区三区在线播放 | arabxxxxvideos | 成人免费一区二区 | 亚洲精品 欧美 | 娇喘视频在线观看 | 精品在线观看一区二区 | 黄色网址入口 | www.91在线观看 | 国产91av视频 | 性欧美一区二区 | 黄色av网站免费 | 日本在线观看一区二区 | 成人在线观看一区二区三区 | 中文字幕在线视频日本 | 欧美成人性色 | 91在线视频网址 | 日本一区二区视频在线 | 免费网站看毛片 | 三级xxxx| 欧美毛片免费观看 | 免费黄色成人 | 成人在线网站 | 在线亚洲综合 | 国产亚洲在 | 91精品国产乱码久久桃 | 91久久久久久久久久久久久 | 看免费5xxaaa毛片 | 国产影院在线观看 | 欧美大穴 | 久久久久久久国产视频 | 久草免费资源视频 | 日韩av成人 | 97人人草| 中国女人内谢69xxxx天美 | 久久人添人人爽人人爽人人片av | 精品国产乱码久久久久久久久 |