- 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. 不如序列类型取值灵活,是一次性的,只能往后取值,不能往前退
来源: http://www.bubuko.com/infodetail-2082987.html