#-*- coding:utf-8 -*-import functoolsimport types'''請編寫一個decorator,能在函數調用的前後列印出'begin call'和'end call'的日誌。'''#這個不難def logt(text): def log(func): @functools.wraps(func) def wrapper(*args,**kw): print '%s %s():'% (text,func.__name__) func(*args,**kw) print 'finish %s():'% func.__name__ return wrapper return log@logt('execute')def current3(): print 'nihaoa'current3()'''再思考一下能否寫出一個@log的decorator,使它既支援:@logdef f(): pass又支援:@log('execute')def f(): pass'''#這個就有點難為我了,我就在此淪陷啦#首先要使用預設值,這一點還是比較清楚的#以下代碼為模仿別人的def log(text='execute'): def logdecorate(func): @functools.wraps(func) def wrapper(*args,**kw): ''' 如果text有值,那就要列印出該值 如果沒值,那就列印預設值,所以都是 text ''' print '%s %s()' % (text,func.__name__) return func(*args,**kw) return wrapper ''' 如果text參數有傳值過來的話, 說明用的是log('text'),即log('text')(now) 這個時候要將log('text')轉成logdecorate才成 即函數原型,然後才能變為log('text')(now)==logdecorate(now) 所以有參數時直接返回logdecorate函數 ''' #判斷text是否屬於函數類型 if not isinstance(text,types.FunctionType): #為log('text') return logdecorate ''' 如果沒有傳值過來的話,說明用的是log,即log(now). text==now,其實就是要調用logdecorate(now) 所以無參數時,直接返回調用logdecorate(now)的結果 ''' if isinstance(text,types.FunctionType): #為log形式 return logdecorate(text)@logdef func_one(): print 'log has no args'@log('diff')def func_two(): print 'log has args'func_one()#然後有人用一個程式包含了上面2道題,#我只能在地上挖礦啦.貼出這位前輩的代碼#才疏學淺,解釋不清def log(text='execute'): def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): print "begin call %s():" %(func.__name__) result = func(*args, **kw) if isinstance(text,types.StringType) and len(text) != 0: print 'text 的值為字串類型' print "%s %s()" %(text, func.__name__) else: print "end call %s()" %(func.__name__) return result return wrapper if isinstance(text, types.FunctionType): print text print 'text 的值為函數類型' return decorator(text) else: print text print 'text的值不為函數類型,無參調用函數' return decorator@logdef now(): print 'mult'print 'log 無參數:'now()#log(now)@log('test')def again(): print 'you args'print 'log 帶參數:'again()#log('test')(now)#我還有救麼