1. 程式人生 > >函數語言程式設計之函式返回值&裝飾器

函數語言程式設計之函式返回值&裝飾器

一、函式返回值


1.什麼是函式返回值
顧名思義,函式返回值,就是一個函式的返回值,是一個函式名的情況
2.閉包
以計算多個數之和為例:
方法一:直接呼叫函式
def cacl_sum(*args):
    all_sum = 0
    for i in args:
        all_sum += i
    return all_sum
print cacl_sum(1,2,3,4,5)

執行效果:
15

方法二:採用閉包的方式

def lazy_sum(*args):
    def cacl_sum():
        all_sum = 0
        for
i in args: all_sum += i return all_sum return cacl_sum #呼叫lazy_sum(),得到返回值cacl_sum(是一個函式名)並賦給f f = lazy_sum(1,2,3,4,5) #呼叫 cacl_sum 函式並執行 print f()

注意: 當呼叫閉包 lazy_sum 時, 每次呼叫都返回一個新的函式。

f1 = lazy_sum(1,2,3,4,5)
f2 = lazy_sum(1,2,3,4,5)
print f1==f2
執行效果:
False

二、裝飾器


1.什麼是裝飾器
  • 裝飾器的本質

器,可以理解為函式,裝飾器實質上是用來裝飾函式的,裝飾器就是在原來功能基礎上加上一些其他功能,即在程式執行前或者執行後加上需要的操作。

  • 裝飾器的功能

比如:許可權的驗證,日誌記錄, 函式執行時間統計, 執行函式前預備處理, 執行函式後清理
功能等。

2、裝飾器的應用
<一>
背景:我們假設這麼一個場景,某學生管理系統有不同的功能,我們想在每次執行一個功能的時候,都輸出相同的歡迎語,我們當然可以分別在每個功能上新增這些歡迎的輸出,但是當我們需要更改歡迎語的時候,是不是還得一一更改,那這樣真的是太崩潰了,這個時候,裝飾器就派上用場了

#裝飾器
def addInfo(fun):
    def wrapped():
        print "歡迎使用XXX使用者管理系統......"
        fun()
    return wrapped
# 裝飾器的語法糖,
@addInfo
def login():
    print "login...."
    pass
@addInfo
def sign_in():
    print "sign in......"
    pass
@addInfo
def louout():
    print "logout......"
    pass
@addInfo
def Display_user_info():
    print "Display_user_info......"
    pass

login()
sign_in()
louout()
Display_user_info()

執行效果:
成功地為每一個功能模組都添加了歡迎資訊,當我們需要對歡迎資訊更改的時候,只需要更改該裝飾器即可

歡迎使用XXX使用者管理系統......
login....
歡迎使用XXX使用者管理系統......
sign in......
歡迎使用XXX使用者管理系統......
logout......
歡迎使用XXX使用者管理系統......
Display_user_info......

那麼,我麼怎麼理解裝飾器的語法糖—[email protected]呢???
以login()模組為例:
(1)當我們在呼叫login()的時候,先執行該模組的第一句@addInfo,實質就是將login()函式變為addInfo()函式的引數–(addInfo(login)),fun是形參,login是實參
(2)然後就執行addInfo()函式,該函式的返回值是一個函式名wrapped,
(3)所以接下來就執行函式wrapped()
(4)執行輸出語句print後,順序執行
(5)fun()就是在執行login()函式的內容,正如(1)所述fun是形參,login是實參

綜上,呼叫login()實際上是指向函式wrapped
<二>函式計時器—–被裝飾的函式有引數

import time   #匯入time模組
def timer(fun):
    def wrapper(*args,**kwargs):   #引數型別為可變引數和關鍵字引數
        start_time = time.time()
        time1 = time.ctime()
        print "%s函式執行時間為%s" %(fun.__name__,time1)
        fun(*args,**kwargs)       #引數型別為可變引數和關鍵字引數
        end_time = time.time()
        time1 = end_time - start_time
        print "%s函式運行了%ss" %(fun.__name__,time1)
    return wrapper
@timer
def add(*a):
    print "結果為:%d" %(sum(a))
add(1,2,4,7,8)

執行效果:

add函式執行時間為Mon Jan 15 16:22:02 2018
結果為:22
add函式運行了5.79357147217e-05s

<三>裝飾器帶引數
裝飾器帶引數就需要在該裝飾器外面再包裹一層函式,用來傳參
程式碼:

def addInfo1(a):                   #a是形參
    def addInfo(fun):
        def wrapped():
            print "歡迎使用XXX使用者管理系統%s頁面......" %(a)
            fun()
        return wrapped
    return addInfo
# 裝飾器的語法糖                   
@addInfo1("login")                 #login是實參
def login():
    print "login...."
    pass
@addInfo1("sign in")
def sign_in():
    print "sign in......"
    pass
@addInfo1("logout")
def louout():
    print "logout......"
    pass
@addInfo1("Display_user_info")
def Display_user_info():
    print "Display_user_info......"
    pass

login()
sign_in()
louout()
Display_user_info()

執行效果:

歡迎使用XXX使用者管理系統login頁面......
login....
歡迎使用XXX使用者管理系統sign in頁面......
sign in......
歡迎使用XXX使用者管理系統logout頁面......
logout......
歡迎使用XXX使用者管理系統Display_user_info頁面......
Display_user_info......

這裡的執行和<一>類似,不同的就是,在執行addInfo()函式之前,先執行了addInfo1()函式傳遞了裝飾器的引數,返回了函式名addInfo,然後執行addInfo()函式,接下來就與<一>無異

相關推薦

語言程式設計函式返回&裝飾

一、函式返回值 1.什麼是函式返回值 顧名思義,函式返回值,就是一個函式的返回值,是一個函式名的情況 2.閉包 以計算多個數之和為例: 方法一:直接呼叫函式 def cacl_sum(*args): all_sum = 0 for i

C#語言程式設計可選

      在我們的實際開發中已經會遇到可空型別,而在C#中自從2.0之後就提供了可空型別(Nullable<T>),普通的值型別是不可以賦值為NULL,但是在型別的後面加上問號就變成了可空型別,這樣就可以賦值為NULL了。當然這樣的方式也可以用於函數語言程式設計中,但函數語言程式設計有自己的獨特

Python(九)語法 語言程式設計函式作為返回,lambda)

函式作為返回值 高階函式除了可以接受函式作為引數外,還可以把函式作為結果值返回。 我們來實現一個可變引數的求和。通常情況下,求和的函式是這樣定義的: >>> def sum(*args): ... s=0 ... for x in args: ... s=s+x

Python進階學習筆記——語言程式設計返回函式&閉包

1、返回函式 Python中除了返回函式值之外,還可以返回函式,就像前面說的,函式也可以看做一個變數,那麼返回函式的意義在於什麼呢?——延緩函式的呼叫,有什麼應用場景暫且還不知道,後續理解補充。總之,可以想呼叫該返回的函式的時候再呼叫。 用慕課網上廖老師的例子說明一下:

語言程式設計-bind函式

Bind函式 Bind函式在函數語言程式設計中是如此重要,以至於函數語言程式設計語言會為bind函式設計語法糖。另一個角度Bind函式非常難以理解,幾乎很少有人能通過簡單的描述說明白bind函式的由來及原理。 這篇文章試圖通過“人話”來描述bind函式,並通過淺顯的例項為零函數語言程式設計語言的開發者揭祕bi

Python學習筆記 -- 語言程式設計高階函式

函數語言程式設計 函數語言程式設計(Functional Programming),是一種抽象程度很高的程式設計正規化,純粹的函數語言程式設計語言編寫的函式沒有變數。因此,任意一個函式,只要輸入是確定的,輸出就是確定的。 函數語言程式設計是一種"程式設計正規化"(pro

Python語言程式設計-講解函式

Python函式優點:   函式是使用者自己編寫好的,因為在很多的情況下一個程式的執行需要重複很多的同一種工作,這個時候可以把重複工作的程式碼封裝成一個函式,每次使用的時候只需要呼叫這個函式就可以了,就算實在修改程式碼的時候,我們也只是修改自定一的函式塊的程式碼就可以了,不用修改很多的程式碼,這樣帶給我門的

在Scala中使用語言程式設計函式和高階函式

                                            圖示,這是一個普通

語言程式設計 Python

  1 函數語言程式設計概述      前提:函式在 Python 中是⼀等物件      工具:built-in ⾼階函式;lambda 函式;operator 模組;functools 模組      模式:閉包與裝飾器      替代:⽤用 List Comprehension 可輕鬆替代 m

語言程式設計陣列的語言程式設計

5. 陣列的函數語言程式設計 在本章中,我們將建立一組用於陣列的函式,並用函式式的方法而非命令式的方法來解決常見的問題 5.1 陣列的函式式方法 本節將建立一組有用的函式,並用它們解決陣列的常見問題 本節所建立的所有函式稱為投影函式,把函式應用

語言程式設計組合與管道

7. 組合與管道 昨天我們學習了柯里化與偏函式,當然不能學完就完了,一些經典的函式什麼的還是需要記一下的,比如今天重寫新寫一下看看能不能寫出來,也能加深自己對這方面的理解。 今天我們將要學習的是函式式組合的含義及其實際應用。 Q 函式式組合在函數語言程式設計中被

java8語言程式設計Consumer

Consumer< T>介面接受一個T型別引數,沒有返回值。 public interface Consumer<T> { void accept(T t);

python語言程式設計—高階函式練習題

俗話說:光說不練假把式……學而不思則罔……近來在跟著廖雪峰前輩的python教程學習,做一些題目練習一下 一、python高階函式 1.利用map()函式,把使用者輸入的不規範的英文名字,變為首字母大寫,其他小寫的規範名字。輸入:[‘adam’, ‘LISA’, ‘barT’],

java語言程式設計Supplier

描述:Supplier< T>介面沒有入參,返回一個T型別的物件,類似工廠方法。 原始碼: public interface Supplier<T> { /** * Gets a result. *

javascript語言程式設計curry化

        函數語言程式設計是一種程式設計正規化(程式設計思想,不要以為有啥模板),主要思想是將運算過程儘量寫成一系列巢狀的函式。舉個例子 //宣告式 let d = a + b + c * d; //函式式 let d = add(a,add(b,mul(c,d))

語言程式設計根-拉姆達運算/演算(λ-calculus)

1930s初,普林斯頓大學的邏輯學家阿倫佐·丘奇 (Alonzo Church,1903-1995) 開發出了一種新的形式系統(formal system),即拉姆達運算/演算 (λ-calculus

Java8語言程式設計物件轉換

一.簡單介紹 通常當我們呼叫介面得到資料時需要轉換一個物件成我們內部程式碼中定義的資料結構, 使用java8的Function和Stream‘s map可以很方便高效的完成轉換。 在我們開始之前,有兩個概念要了解。 第一個是一個接受一個引數併產生結果的java.uti

語言程式設計memories

純函式:是這樣一種函式,即相同的輸入,永遠會得到相同的輸出,而且沒有任何可觀察的副作用。這樣的純函式好處便是可以進行快取,稱之為memorize,只是下面的函式不夠健壯function memorize(fn) {    let cache = {}   return fun

Python路-Day08語言程式設計與內建函式

return可以返回任何值 當你在一個函式當中返回一個函式名的時候,其實返回的是這個函式在記憶體當中的地址,如果你用一個變數去接收它,然後以這個變數名執行的話,就會執行你返回的記憶體地址對應的那個函式. def test1(): print("in the test1")

Python路Python作用域、匿名函式語言程式設計、map函式、filter函式、reduce函式 Python路Python作用域、匿名函式語言程式設計、map函式、filter函式、reduce函式

Python之路Python作用域、匿名函式、函數語言程式設計、map函式、filter函式、reduce函式 一、作用域 return 可以返回任意值例子 def test1(): print("test1") def test(): print("te