python中的@符號的作用
- 2020 年 1 月 9 日
- 筆記
'@'符號用作函數修飾符是python2.4新增加的功能,修飾符必須出現在函數定義前一行,不允許和函數定義在同一行。也就是說@A def f(): 是非法的。只可以在模組或類定義層內對函數進行修飾,不允許修修飾一個類。一個修飾符就是一個函數,它將被修飾的函數做為參數,並返回修飾後的同名函數或其它可調用的東西。
實例(1):
def spamrun(fn): def sayspam(*args): print "spam,spam,spam" return sayspam
@spamrun def useful(a,b): print a**2+b**2 useful(3,4)
結果:
spam,spam,spam
實例(2):
def spamrun(fn): print "spam,spam,spam"
@spamrun def useful(a,b): print a**2+b**2
結果:
spam,spam,spam
實例(3):
def spamrun(fn): def sayspam(*args): print "spam,spam,spam" return sayspam
@spamrun def useful(a,b): print a**2+b**2 useful(3,4)
結果:
spam,spam,spam
實例(4):
def addspam(fn): def new(*args): print "spam,spam,spam" return fn(*args) return new
@addspam def useful(a,b): print a**2+b**2 useful(4,3)
結果:
spam,spam,spam 25
追加
實例
def decorator(fn): def test(*args): print "My god!"*3 return fn(*args) return test
@decorator def other(a,b): print a**2+b**2
if __name__=="__main__": other(4,3) other(3,4) 結果:
My god!My god!My god! 25 My god!My god!My god! 25 注釋掉//print return fn(*args)
結果是:
My god!My god!My god! My god!My god!My god! 要想使other函數能正常運行,必須加返回值,@decorator是一個statement,會將other函數當作參數傳入來執行test方法。
自補1
大家來看下面的程式碼:
def masterwebHandle(cls): ''' ''' root.putChild(cls.__name__, cls()) @masterwebHandle class stop(resource.Resource): '''stop service''' def render(self, request): ''' ''' for child in GlobalObject().root.childsmanager._childs.values(): d = child.callbackChild('serverStop') d.addCallback(ErrorBack) reactor.callLater(0.5,reactor.stop) return "stop" 上述內容來自於Firefly框架中的ireflymaster下的webapp.py。
自補2
我們知道,Python中並沒有提供直接的介面支援,但是介面技術又是現代軟體設計中的重要技術,藉助於它可以極大地減小軟體模組間的耦合度。於是,藉助於zope.interface,python中也可以引入介面技術。
具體的內部細節在此不展開了,直接上程式碼:
#其他省略
from zope.interface import implementer #利用這些zope.interface中implementer等技術,實現了類似於其他高級語言中的極簡化的介面操作
from twisted.internet.interfaces import IReactorFDSet
#……
@implementer(IReactorFDSet) class _ContinuousPolling(posixbase._PollLikeMixin, posixbase._DisconnectSelectableMixin):
#……
def addReader(self, reader): """ Add a C{FileDescriptor} for notification of data available to read. """ self._readers.add(reader) self._checkLoop()
def addWriter(self, writer): """ Add a C{FileDescriptor} for notification of data available to write. """ self._writers.add(writer) self._checkLoop()
其中,介面IReactorFDSet的部分程式碼如下(介面中只是簡單地聲明函數,而且注意成員函數參數中沒有上面的self):
class IReactorFDSet(Interface): def addReader(reader):
def addWriter(writer):