名称空间
又叫命名空间,名字空间,英文名叫 name space,干嘛用的?
假如有 x = 1 , 1是存放到内存的,那 x 存哪里的呢?名称空间正式存放名字x与1绑定关系的地方。
名称空间分3种:
- locals:是函数内的名称空间,包括局部变量和形参。通过locals()可以打印当前名称空间的局部变量,如果在函数里就是函数里的局部变量。
- globals:全局变量,函数定义所在模块的名字空间。通过globals()可以打印所有的全局变量,无论是在函数内还是函数外。
- builtins:内置模块的名字空间。可通过dir(__builtins__)打印所有的内置方法
不同变量的作用域不同就是由这个变量所在的命名空间来决定的。
作用域即范围:
- 全局范围:全局存活,全局有效
- 局部范围:临时存活,局部有效。
作用域查找顺序:
LEGB代表名字查找顺序:locals --> enclosing function --> globals --> __builtins__
- locals:是函数内的名字空间
- enclosing:外部嵌套函数的名字空间
- globals:全局变量,函数定义所在模块的名字空间
- builtins:内置模块的名字空间
闭包
首先看例子:
def func(): name = "Alex" def inner(): print("在inner里打印name:", name) return inner f = func() f()
输出:
在inner里打印name: Alex
以上例子可以看出,嵌套函数中,直接执行func函数,里面的inner函数并没有执行,而是func函数将inner函数对象返回给了外部,给到了f ,这时候 f 实际上就是inner函数,f 加上括号就相当于直接执行inner函数。这样使得嵌套在函数内的子函数在外部也可被调用执行,调用的时候依然能够获取inner函数所在作用域的变量以及参数。
关于闭包,即函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数。当其中一个这样的内部函数在包含他们的外部函数之外被调用时,就会形成闭包。也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必须访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。
闭包的意义:
返回的函数对象,不仅仅是一个函数对象,在改函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域。
装饰器
内容太多了,还是直接看大王的故事:
http://www.cnblogs.com/alex3714/articles/5765046.html
装饰器就是在不修改原来程序的情况下给程序添加新的功能。
软件开发中的一个原则:开放-封闭 原则
开放:已实现的功能代码块不应该被修改
封闭:对现有功能的扩展开放
装饰器练习题
''' 一:编写3个函数,每个函数执行的时间是不一样的, 提示:可以使用time.sleep(2),让程序sleep 2s或更多, 二:编写装饰器,为每个函数加上统计运行时间的功能 提示:在函数开始执行时加上start=time.time()就可纪录当前执行的时间戳,函数执行结束后在time.time() - start就可以拿到执行所用时间 三:编写装饰器,为函数加上认证的功能,即要求认证成功后才能执行函数 四:编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码 提示:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式 ''' import time def runtime(func): def inner(): start_time = time.time() func() end_time = time.time() run_time = end_time - start_time print("run time:", run_time) return inner def get_account_from_file(): f = open("account2.txt", mode="r", encoding="utf-8") data = eval(f.read()) f.close() return data login_status = False def login(func): def inner(*args, **kwargs): global login_status if login_status == False: username = input("username:>") password = input("password:>") account_dict = get_account_from_file() if username == account_dict["name"] and password == account_dict["password"]: print("登录成功") login_status = True else: print("用户名或密码错误.") if login_status: print("已通过验证..") func(*args, **kwargs) return inner @login @runtime def func1(): print("func1 running...") time.sleep(2) @login @runtime def func2(): print("func2 running...") time.sleep(3) @login @runtime def func3(): print("func3 running...") time.sleep(1) func1() func2() func3()
列表生成式
有一个需求是 有一个列表,要对列表里的每个元素加1,如何做,有以下几种:
# 版本一: a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] b = [] for i in a: b.append(i + 1) print(b) # 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 版本二: c = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] for index, i in enumerate(c): c[index] = i + 1 print(c) # 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 版本三: d = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] d = list(map(lambda x: x + 1, d)) print(d) # 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 版本四:列表生成式 e = [i + 1 for i in range(10)] print(e) # 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
f = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] f = [i if i < 5 else i * i for i in f] # 列表生成式 print(f) # 输出:[0, 1, 2, 3, 4, 25, 36, 49, 64, 81]