Python中的注解“@”

Python3.0之后加入新特性Decorators,以@為標記修飾function和class牺蹄。有點類似c++的宏和java的注解沃缘。Decorators用以修飾約束function和class,分為帶參數(shù)和不帶參數(shù)孵奶,影響原有輸出,例如類靜態(tài)函數(shù)我們要表達的時候需要函數(shù)前面加上修飾@staticmethod或@classmethod,為什么這樣做呢蜡峰?下面用簡單的例子來看一下了袁,具體內(nèi)容可以查看:官方解釋

不帶參數(shù)的單一使用

def spamrun(fn):
    def sayspam(*args):
        print("spam,spam,spam")
        fn(*args)
    return sayspam
@spamrun
def useful(a,b):
    print(a*b)
   
if __name__ == "__main__"
    useful(2,5) 

運行結(jié)果

spam,spam,spam
10

函數(shù)useful本身應(yīng)該只是打印10,可是為什么最后的結(jié)果是這樣的呢湿颅,其實我們可以簡單的把這個代碼理解為

def spamrun(fn):
    def sayspam(*args):
        print("spam,spam,spam")
        fn(*args)
    return sayspam
    
def useful(a,b):
    print(a*b)
   
if __name__ == "__main__"
    useful = spamrun(useful)
    useful(a,b)

不帶參數(shù)的多次使用

def spamrun(fn):
    def sayspam(*args):
        print("spam,spam,spam")
        fn(*args)
    return sayspam


def spamrun1(fn):
    def sayspam1(*args):
        print("spam1,spam1,spam1")
        fn(*args)
    return sayspam1
        
@spamrun
@spamrun1
def useful(a,b):
    print(a*b)
   
if __name__ == "__main__"
    useful(2,5) 

運行結(jié)果

spam,spam,spam
spam1,spam1,spam1
10

這個代碼理解為

if __name__ == "__main__"
    useful = spamrun1(spamrun(useful))
    useful(a,b)

帶參數(shù)的單次使用

def attrs(**kwds):
    def decorate(f):
        for k in kwds:
            setattr(f, k, kwds[k])
        return f

    return decorate


@attrs(versionadded="2.2",
       author="Guido van Rossum")
def mymethod(f):
    print(getattr(mymethod,'versionadded',0))
    print(getattr(mymethod,'author',0))
    print(f)
   
if __name__ == "__main__"
mymethod(2) 

運行結(jié)果

2.2
Guido van Rossum
2

這個代碼理解為

if __name__ == "__main__"
    mymethod = attrs(versionadded="2.2",
        author="Guido van Rossum).(mymethod)
    mymethod(2)

帶參數(shù)的多次使用

這次我們來看一個比較實際的例子载绿,檢查我們函數(shù)的輸入輸出是否符合我們的標準,比如我們希望的輸入是(int油航,(int崭庸,float))輸出是(int,float),這個例子在官網(wǎng)里有冀自,但是在3.6版本中使用有些問題揉稚,這里進行了一些改動,如果要進一步了解可以看下functionTool熬粗。

def accepts(*types):
    def check_accepts(f):
        def new_f(*args, **kwds):
            assert len(types) == (len(args) + len(kwds)), \
                "args cnt %d does not match %d" % (len(args) + len(kwds), len(types))
            for (a, t) in zip(args, types):
                assert isinstance(a, t), \
                    "arg %r does not match %s" % (a, t)
            return f(*args, **kwds)

        update_wrapper(new_f, f)
        return new_f

    return check_accepts


def returns(rtype):
    def check_returns(f):
        def new_f(*args, **kwds):
            result = f(*args, **kwds)
            assert isinstance(result, rtype), \
                "return value %r does not match %s" % (result, rtype)
            return result

        update_wrapper(new_f, f)
        return new_f

    return check_returns


@accepts(int, (int, float))
@returns((int, float))
def func(arg1, arg2):
    return arg1 * arg2  
    
if __name__ == "__main__"
    a = func(1, 'b')
    print(a)    

這里故意輸入了錯誤的參數(shù)搀玖,所以運行結(jié)果將我們的斷言打印了出來

AssertionError: arg 'b' does not match (<class 'int'>, <class 'float'>)

這個代碼理解為

if __name__ == "__main__"
    func = accepts(int, (int, float)).(accepts((int, float)).(mymethod))
    a = func(1, 'b')
    print(a)

說到這里,大家不難看出其實我們可以使用Decorators做很多工作驻呐,簡化代碼灌诅,使邏輯更清晰等。還有更多的用法等著大家自己去挖掘了含末,這里只簡單的介紹了針對函數(shù)的用法猜拾,其實還可以針對class使用,具體的大家自己看看官方介紹佣盒,結(jié)合這篇文檔應(yīng)該就不難理解了挎袜。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市肥惭,隨后出現(xiàn)的幾起案子盯仪,更是在濱河造成了極大的恐慌,老刑警劉巖蜜葱,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件全景,死亡現(xiàn)場離奇詭異,居然都是意外死亡牵囤,警方通過查閱死者的電腦和手機爸黄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來揭鳞,“玉大人炕贵,你說我怎么就攤上這事⌒阼耄” “怎么了鲁驶?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵鉴裹,是天一觀的道長舞骆。 經(jīng)常有香客問我,道長径荔,這世上最難降的妖魔是什么督禽? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮总处,結(jié)果婚禮上狈惫,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好胧谈,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布忆肾。 她就那樣靜靜地躺著,像睡著了一般菱肖。 火紅的嫁衣襯著肌膚如雪客冈。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天稳强,我揣著相機與錄音场仲,去河邊找鬼。 笑死退疫,一個胖子當著我的面吹牛渠缕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播褒繁,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼亦鳞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了棒坏?” 一聲冷哼從身側(cè)響起蚜迅,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎俊抵,沒想到半個月后谁不,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡徽诲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年刹帕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谎替。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡偷溺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钱贯,到底是詐尸還是另有隱情挫掏,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布秩命,位于F島的核電站尉共,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏弃锐。R本人自食惡果不足惜袄友,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望霹菊。 院中可真熱鬧剧蚣,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至目尖,卻和暖如春叹坦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卑雁。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工募书, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人测蹲。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓莹捡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親扣甲。 傳聞我的和親對象是個殘疾皇子篮赢,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法琉挖,內(nèi)部類的語法启泣,繼承相關(guān)的語法,異常的語法示辈,線程的語...
    子非魚_t_閱讀 31,657評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理寥茫,服務(wù)發(fā)現(xiàn),斷路器矾麻,智...
    卡卡羅2017閱讀 134,693評論 18 139
  • 前言 人生苦多纱耻,快來 Kotlin ,快速學(xué)習(xí)Kotlin险耀! 什么是Kotlin弄喘? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,217評論 9 118
  • 說起人生,很多人對于這個虛幻而龐大的概念很是模糊甩牺,包括我蘑志,當然,每個人的人生軌跡都不一樣贬派,自然而然對于人生...
    我是嘻哈大哥閱讀 773評論 0 0
  • 1 再長久的一生 不也就只是 就只是 回首時 那短短的一瞬 2 我可以鎖住我的筆 為什么 卻鎖不住愛和憂傷...
    A1dna閱讀 615評論 0 8