1.名称空间 python有三种名称空间 内置名称空间: 随着python解释器的启动而产生 print(sum) print(max) 全局名称空间: 文件的执行会产生全局名称空间,指的是文件级别的定义名字都会放入该空间 x = 11 if x == 11: print(x) 局部名称空间: 调用函数时会产生局部名称空间,只在函数调用时临时绑定,调用结束时解绑 x = 1000 def foo(): x = 1 print(x) foo() print(x) 作用域: 1.全局作用域: 内置名称空间,全局名称空间,全局有效,在任何位置都能被访问到, 除非del删除,否则存活到文件结束。 2.局部作用域: 局部名称空间,局部有效,只能在局部范围调用,调用结束失效。 名字的查找顺序: 局部名称空间-->全局名称空间-->内置名称空间 x = 1000 def func(): x = 2 print(locals()) #locals()查看局部作用域内的名字 print(globals()) #globals()查看全局作用域内的名字 2.函数对象 1.可以被引用 2.可以当作参数传递 3.返回值可以是函数 4.可以当作容器类型的元素 例子: def foo(): print("from foo") func = foo print(foo) print(func) foo() func() def foo(): print("from foo") def bar(func): print(func) func() bar(foo) def foo(): print("from foo") dic = {'func': foo} print(dic['func']) dic['func']() 3.闭包函数 闭包: 1.定义在内部函数 2.包含对外部作用域而非全局作用域的引用 该内部函数就称作闭包函数 例子: def f1(): x = 1 def f2(): #f2称作闭包函数 print(x) return f2 f = f1() print(f) #打印f2函数的内存地址 f() #打印1 例子: from urllib.request import urlopen def index(url): def get(): return urlopen(url).read() return get oldboy = index('http://www.baidu.com') print(oldboy().decode('utf-8')) print(oldboy.__closure__[0].cell_contents) #打印外部引用而非全局引用对象 4.装饰器 修饰其他对象的工具,修饰添加功能,工具指的是函数。 装饰器本身是任何可调用对象,被装饰的对象也可以是任何可调用的对象。 为什么要用装饰器? 开放封闭原则,对修改是封闭的,对扩展是开放的。 装饰器就是为了在不修改被装饰对象源代码以及调用方式的前提下,为其添加新功能 装饰器相当于闭包的实现 例子: import time def timmer(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) stop_time = time.time() print("run time is {0}".format(stop_time - start_time)) return wrapper @timmer #相当于index = timmer(index) def index(): time.sleep(3) print("welcome to index") return 1 index() #其实相当于执行了timmer(index) 例子: import time def timmer(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) stop_time = time.time() print("run time is {0}".format(stop_time - start_time)) return wrapper def index(): time.sleep(3) print("welcome to index") f = timmer(index) print(f) f() #f()<=====>wrapper() 认证用户登录 login_user = {'user': None, 'status': False} def auth(func): def wrapper(*args, **kwargs): if login_user['user'] and login_user['status']: res = func(*args, **kwargs) return res else: name = input("请输入姓名:") passwd = input("请输入密码:") if name == "hyh" and passwd == "123": login_user['user'] = "hyh" login_user['status'] = True print("\033[45mlogin successful\033[0m") res = func(*args, **kwargs) return res else: print("\033[45mlogin err\033[0m") return wrapper @auth def index(): print("welcome to index page") @auth def home(name): print("%s welcome to home page" % (name)) index() home("hyh") 5.迭代器 迭代器的概念: 重复上一次迭代的结果为下一次迭代的初始值,重复的过程称为迭代, 每次重复即一次迭代 为什么要有迭代器? 对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式 可迭代对象: 内置__iter__方法的都是可迭代对象 [1,2].__iter__() 'hello'.__iter__() (1,2).__iter__() {"a":1, "b": 2}.__iter__() {1,2,3}.__iter__() 迭代器: 执行__iter__()方法,得到的结果就是迭代器,迭代器有__next__()方法 i = [1,2,3].__iter__() print(i.__next__()) #打印1 print(i.__next__()) #打印2 print(i.__next__()) #打印3 print(i.__next__()) #抛出异常 i__iter__() <==>iter(i) i__next__() <==>next(i) 如何判断一个对象是可迭代对象,还是迭代器对象 from collections import Iterable, Iterator print(isinstance('abc',Iterable)) print(isinstance([],Iterable)) print(isinstance((),Iterable)) print(isinstance({'a':1},Iterable)) print(isinstance({1,2},Iterable)) f=open('a.txt','w') f.__iter__() print(isinstance(f,Iterable)) #只有文件是迭代器对象 可迭代对象:只有__iter__方法,执行该方法得到的迭代器对象 迭代协议: 对象有__next__ 对象有__iter__,对于迭代器对象来说,执行__iter__方法,得到的结果仍然是它本身 迭代器的优点和缺点 优点: 1.提供了一种不依赖下标的迭代方式 2.就跌迭代器本身来说,更节省内存 缺点: 1. 无法获取迭代器对象的长度 2. 不如序列类型取值灵活,是一次性的,只能往后取值,不能往前退 6.生成器 生成器函数: 只要函数体包含yield关键字,该函数就是生成器函数,生成器就是迭代器 例子: def foo(): print("first") yield 1 print("second") yield 2 print("third") yield 3 print("fourth") g = foo() for i in g: print(i) print(next(g)) #出发迭代器g的执行,进而出发函数 print(next(g)) yield的功能: 1.相当于为函数封装好__iter__和__next__函数 2.return只能返回一次值就终止了 3.yield能返回多次值,每次返回将函数暂停,下一次next从上一次暂停的位置继续 模拟tail -f |grep "python" 例子: import time def tail(file): with open(file, encoding='utf-8') as f: line = f.readline().strip() if line: yield line else: time.sleep(0.2) t = tail('a.txt') for line in t: print(line) def grep(pattern, lines): for line in lines: if pattern in line: yield line g = grep("python", tail('one.py')) print(g) for i in g: print(i) yield两种用法 1.语句形式: yield 1 2.表达式用法: x = yield 例子: def deco(func): def wrapper(*args, **kwargs): res = func(*args, **kwargs) next(res) #相当于res.send(None)初始化生成器 return res return wrapper @deco def eater(name): print("%s ready to eat" %name) food_list = [] while True: food = yield food_list food_list.append(food) print('%s start to eat %s' %(name, food)) g = eater('alex') v = g.send("脚趾头") #返回food_list列表 print(v) #send()函数发送数据给yield,跟next作用很相似,只是它能发送数据
python学习之函数学习进阶
精选 原创
©著作权归作者所有:来自51CTO博客作者小白的希望的原创作品,请联系作者获取转载授权,否则将追究法律责任
上一篇:python学习之函数学习进阶
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
python学习之函数进阶三
python学习函数进阶,内置模块介绍,及使用方法
函数 学习 python -
python 魔法函数学习
魔法函数学习
python 应用场景 Test 魔法函数