最近想整一整数据分析,在看一本关于数据分析的书中提到了(1)if __name__ == '__main__' (2)列表解析式 (3)装饰器。html
先简单描述一下前两点,再详细解说Python初级的函数装饰器。python
进入正题:app
1、if __name__ == '__main__' 函数
1 def printHello(): 2 print("Hello World!") 3 print(__name__) 4 if __name__ == '__main__': 5 printHello()
其输出以下:测试
Hello World! __main__
由于此时这个文件是以主程序的方式运行的,故它的__name__为__main__。spa
1 from name_main import printHello 2 printHello()
咱们只会获得 printHello 运行一次的结果。这一次结果是 import 语句的效果,真正的 printHello 函数被 if 语句拦住了(由于它的__name__变成了本身的文件名而非__main__)。code
2、列表解析式htm
3、装饰器对象
#直接装饰@ def printname(func): #装饰器:实质是一个函数,参数是须要装饰的函数名(非函数调用) def wrapper(*args, **kwargs): #可变参数*args和关键字参数**kwargs print(f"[DEBUG]: enter {func.__name__}()") return func(*args, **kwargs) return wrapper #装饰器函数返回的是装饰完的函数 @printname def say_hello(): print("hello!") @printname def say_goodbye(): print("goodbye!") if __name__ == '__main__': say_hello() say_goodbye()
程序运行结果为:blog
[DEBUG]: enter say_hello()
hello!
[DEBUG]: enter say_goodbye()
goodbye!
成功实现每次打印hello时打印出函数名称say_hello()。
#间接装饰 def printname(func): #装饰器:实质是一个函数,参数是须要装饰的函数名(非函数调用) def wrapper(*args, **kwargs): #可变参数*args和关键字参数**kwargs print(f"[DEBUG]: enter {func.__name__}()") return func(*args, **kwargs) return wrapper #装饰器函数返回的是装饰完的函数 def say_hello(): print("hello!") #return 0 测试line:23 def say_goodbye(): print("goodbye!") if __name__ == '__main__': decorator = printname(say_hello) ''' 不能使用decoratot = printname(say_hello()); 多是由于调用函数的名称是用func.__name__,而非func().__name__ 用了func().name会报错'NoneType'对象没有'__name__'属性。 由于say_hello()函数没有return,故执行结果为NoneType无。 ''' decorator() ''' 接上绿色注释: >>> type(say_hello()) hello! <class 'NoneType'> >>> type(say_hello) <class 'function'> ''' #func,函数不带括号时,调用的是这个函数自己。是一整个函数体,不须等函数执行完成。 #func(),函数带括号时,调用的是函数的执行结果,须要等待函数执行完成的结果。
和@方法的区别主要在于如何使用装饰器函数。咱们须要在调用时把执行函数传入给装饰函数,return 的结果返回给新函数;再运行新函数,就实行了这一效果。
1 def printname(func): 2 def wrapper(*args, **kwargs): 3 print(f"[DEBUG]: enter {func.__name__}()") 4 return func(*args, **kwargs) 5 return wrapper
实现了:print(装饰)+ func(执行函数),即成功装饰。
实质: 是一个函数
参数:是你要装饰的函数名(并不是函数调用)
返回:是装饰完的函数名(也非函数调用)
做用:为已经存在的对象添加额外的功能
特色:不须要对对象作任何的代码上的变更