那麼,爲了簡化它,首先我們來處理函數。比方說,你有一個打印一些關於它的參數的函數:
def print_info(breed, name):
print "The doggie %s's breed is %s." % (name, breed)
這樣:
>>> print_info("Labrador", "Spike")
The doggie Spike's breed is Labrador.
>>> print_info("Pit Bull", "Spot")
The doggie Spot's breed is Pit Bull.
現在你想要的功能,而不是總是小寫的品種。因此,在一個健全的方式你只是這樣做:
def manually_lowered_print_info(breed, name):
print "The doggie %s's breed is %s." % (name, breed.lower())
輸出是:
>>> manually_lowered_print_info("Labrador", "Spike")
The doggie Spike's breed is labrador.
但是,假設由於某種原因,你經常不得不爲小寫的函數的第一個字符串參數,你寫了這麼你想把它作爲裝飾者來抽象出來。我們希望它看起來像這一點,並具有相同的輸出:
@lower_first_arg
def dec_lowered_print_info(breed, name):
print "The doggie %s's breed is %s." % (name, breed)
這只是語法糖這樣的:
def tmp_func(breed, name):
print "The doggie %s's breed is %s." % (name, breed)
dec_lowered_print_info = lower_first_arg(tmp_func)
因此,我們要lower_first_arg
到回報轉化print_info
功能。我們首先爲print_info
函數定製一個函數。
def lower_first_arg(print_info_func_arg):
def inner_print_info(breed, name):
return print_info_func_arg(breed.lower(), name)
return inner_print_info
它工作嗎?讓我們看看:
>>> transformed_print_info = lower_first_arg(print_info)
>>> print_info("Pit Bull", "Spot")
The doggie Spot's breed is Pit Bull.
>>> transformed_print_info("Pit Bull", "Spot")
The doggie Spot's breed is pit bull.
太棒了!請注意,我們將print_info
作爲參數傳遞給lower_first_arg
函數,它被本地變量print_info_func_arg
引用。
如果我們使用修飾語法它的工作原理相同:
@lower_first_arg
def dec_lowered_print_info(breed, name):
print "The doggie %s's breed is %s." % (name, breed)
突出:
>>> dec_lowered_print_info("Pit Bull", "Spot")
The doggie Spot's breed is pit bull.
酷,所以就是這樣,真的。現在,爲了裝飾更通用,讓我們先概括名稱:
def generic_lower_first_arg(f):
def wrapped(arg1, arg2):
return f(arg1.lower(), arg2)
return wrapped
現在這裏的問題是這個裝飾只適用於2個ARGS功能。理想情況下,我們希望它能夠處理1個或更多的任何函數,例如:
@generic_lower_first_arg
def failed_whatnow(first, last, middle):
print "%s %s %s" % (first, middle, last)
現在,該代碼將運行,但我們得到一個錯誤,如果我們試圖把它叫做:
>>> failed_whatnow("Bob", "Jones", "The Killer")
Traceback (most recent call last):
File "<pyshell#26>", line 1, in <module>
failed_whatnow("Bob", "Jones", "The Killer")
TypeError: wrapped() takes exactly 2 arguments (3 given)
這是怎麼回事?那麼,裝飾器拿了failed_whatnow
並返回了它定義的函數wrapped
,但wrapped
函數只有兩個參數!這裏的解決方法是使用可變參數語法。傳遞可能賦予包裝函數的關鍵字參數通常也是一個好主意。
def proper_lower_first_arg(f):
def wrapped(arg1, *args, **kwargs):
return f(arg1.lower(), *args, **kwargs)
return wrapped
而現在它適用於各種功能:
@proper_lower_first_arg
def proper_whatnow(first, last, middle):
print "%s %s %s" % (first, middle, last)
@proper_lower_first_arg
def multiplyit(mm, n=3):
return mm * n
證明:
>>> proper_whatnow("Bob", "Jones", "The Killer")
bob The Killer Jones
>>> multiplyit("HaHa.Fool!")
'haha.fool!haha.fool!haha.fool!'
>>> multiplyit("HaHa.Fool!", n=5)
'haha.fool!haha.fool!haha.fool!haha.fool!haha.fool!'
到底是什麼,你正在尋找的輸出?是不是像string.lower()函數那樣小寫,但是你想用ascii值來實現它? – RMcG
恩,我不確定你剛纔問的是哪一件。爲了澄清,沒有一個對我很重要,我只是試圖實現某種裝飾器來了解更多關於裝飾器的知識。 – stephan
如果你想要去比特級這篇文章應該幫助http://stackoverflow.com/questions/3569874/how-do-uppercase-and-lowercase-letters-differ-by-only-one-bit/3570520# 3570520 – RMcG