您的位置:首页 > 编程语言 > Python开发

第4章 python闭包函数 装饰器 迭代器 生成器

2017-07-28 11:24 861 查看
一.名称空间
#名称空间:存放名字的地方,准确的说名称空间是存放名字与变量值绑定关系的地方

#内置名称空间:在python解释器启动时产生,存放一些python内置的名字
#全局名称空间:在执行文件时产生,存放文件级别定义的名字
# x=1
# def func():
# y=2
# def f1():pass
# print
#
#
# import os
#
# class Foo:
# pass
#
# if x==1:z=3

# del x

#局部名称空间:在执行文件的过程中,如果调用了函数,则会产生该函数的局部名称空间
#用来存放该函数内定义的名字,该名字在函数调用时生效,在函数调用结束后失效

#加载顺序:内置---》全局---》局部

#优先掌握一:名字的查找顺序是:局部-》全局-》内置

# # max=1
# def foo():
# max=2
# # print(max)
#
# foo()
# print(max)

#作用域:作用的范围,
#全局作用域:全局存活,全局有效:globals()
# max=1111111
# def f1():
# def f2():
# def f3():
# def f4():
# # print(x)
# print(max)
# f4()
# f3()
# f2()
#
#
# f1()
#局部作用域:临时存活,局部有效:locals()

x=11111111111111111111111111111111111111111111

# def f1():
# x=1
# y=2
# def f2():pass
# # print(locals())
# print(globals())
#
# f1()
# print(locals() is globals())
# print(locals())
#
# print(dir(globals()['__builtins__']))

#global nonlocal掌握
# x=1
# def f1():
# global x
# x=2
#
# f1()
# print(x)

# l=[]
# def f2():
# l.append('f2')
#
# f2()
# print(l)

# x=0
# def f1():
# # x=1
# def f2():
# # x=2
# def f3():
# # global x
# nonlocal x
# x=3
# f3()
# # print(x)
# f2()
# print(x)
# f1()
# print(x)

#优先掌握二:作用域关系,在函数定义时就已经固定
# ,于调用位置无关,在调用函数时,必须必须必须
#回到函数原来定义的位置去找作用域关系

x=1
def f1():
def f2():
print(x)
return f2

# func=f1()
# print(func)
# x=10000000
# func()
# x=10000000

def foo(func):
x=300000000
func() #f2()
x=10000000000000000000000

foo(f1())
# x=10000000000000000000000
# foo(f1())

二.闭包函数
#1. 定义在函数内部的函数
#2. 包含对外部作用域名字的引用,而不是对全局作用域名字的引用
#那么该内部函数就称为闭包函数

# 闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域应用领域:延迟计算(原来我们是传参,现在我们是包起来)

三.装饰器
#1 开放封闭原则:对扩展是开放的,对修改是封闭

#2 装饰器:装饰它人的工具,
#装饰器本身可以是任意可调用对象,被装饰的对象本身也可以是任意可调用对象

#2.1 装饰器的遵循的原则:1 不修改被装饰对象的源代码 2 不修改被调用对象的调用方式
#2.2 装饰器的目的是:在遵循1和2原则的前提,为其他新功能函数添加

#@装饰器名,必须写在被装饰对象的正上方,并且是单独一行
import time

def timmer(func):
# func=index
def wrapper():
start=time.time()
func()
stop=time.time()
print('run time is %s' %(stop-start))
return wrapper

@timmer # index=timmer(index)
def index():
time.sleep(3)
print('welcome to index')
@timmer # home=timmer(home)
def home():
time.sleep(2)
print('welcome to home page')

index()
home()

四.迭代器
#迭代:是一个重复的过程,每一次重复,都是基于上一次的结果而来
# while True: #单纯的重复
# print('hello world')

# l=['a','b','c','d']
# count=0
# while count < len(l):
# print(l[count])
# count+=1

dic={'name':'egon','sex':'m',"age":18} #上述按照索引的取值方式,不适于没有索引的数据类型

#迭代器:
#可迭代对象iterable:凡是对象下有__iter__方法:对象.__iter__,该对象就是可迭代对象
# s='hello'
# l=['a','b','c','d']
# t=('a','b','c','d')
# dic={'name':'egon','sex':'m',"age":18}
# set1={1,2,3}
# f=open('db.txt')

# s.__iter__()
# l.__iter__()
# t.__iter__()
# dic.__iter__()
# set1.__iter__()
# f.__iter__()

#迭代器对象:可迭代对象执行内置的__iter__方法,得到的结果就是迭代器对象

# dic={'name':'egon','sex':'m',"age":18}
#
# i=dic.__iter__()
# # print(i) #iterator迭代器
#
# # i.__next__() #next(i)
# print(next(i))
# print(next(i))
# print(next(i))
# print(next(i)) #StopIteration
#
# l=['a','b','c','d']
#
# i=l.__iter__()
# print(next(i))
# print(next(i))
# print(next(i))
# print(next(i))
# print(next(i)) #StopIteration

#不依赖于索引的取值方式
# l=['a','b','c','d']
# dic={'name':'egon','sex':'m',"age":18}
# iter_l=iter(l)
# iter_dic=iter(dic)
# while True:
# try:
# # print(next(iter_l))
# k=next(iter_dic)
# print(k,dic[k])
# except StopIteration:
# break

#什么是迭代器对象:
#1 有__iter__,执行得到仍然是迭代本身
#2 有__next__

#迭代器对象的优点
#1:提供了一种统一的(不依赖于索引的)迭代方式
#2:迭代器本身,比起其他数据类型更省内存
# l=['a','b','c','d']
# i=iter(l)

# dic={'a':1,'b':2}
# x=dic.keys()
# print(x)
# i=x.__iter__()
#
# with open('a.txt') as f:
# # print(next(f))
# # print(next(f))
# # print(next(f))
# f.read()

#迭代器对象的缺点
#1:一次性,只能往后走,不能回退,不如索引取值灵活
#2:无法预知什么时候取值结束,即无法预知长度
# l=['a','b','c','d']
# i=iter(l)
# print(next(i))
# print(next(i))
# print(next(i))

五.生成器
#生成器:在函数内部包含yield关键,那么该函数执行的结果是生成器
#生成器就是迭代器
#yield的功能:
# 1 把函数的结果做生迭代器(以一种优雅的方式封装好__iter__,__next__)
# 2 函数暂停与再继续运行的状态是由yield

# def func():
# print('first')
# yield 11111111
# print('second')
# yield 2222222
# print('third')
# yield 33333333
# print('fourth')
#
#
# g=func()
# print(g)
# from collections import Iterator
# print(isinstance(g,Iterator))

# print(next(g))
# print('======>')
# print(next(g))
# print('======>')
# print(next(g))
# print('======>')
# print(next(g))

# for i in g: #i=iter(g)
# print(i)

# def func(n):
# print('我开动啦')
# while True:
# yield n
# n+=1
#
# g=func(0)
#
# # print(next(g))
# # print(next(g))
# # print(next(g))
# for i in g:
# print(i)

#
# for i in range(10000):
# print(i)

# def my_range(start,stop):
# while True:
# if start == stop:
# raise StopIteration
# yield start #2
# start+=1 #3
#
# g=my_range(1,3)
# #
# print(next(g))
# print(next(g))
# print(next(g))
#

#
# for i in my_range(1,3):
# print(i)

#yield与return的比较?
#相同:都有返回值的功能
#不同:return只能返回一次值,而yield可以返回多次值

六.三元表达式,列表推导式,生成器表达式
==============================#三元表达式
name='hello'
name='cc'
res='hello' if name == 'hello' else 'world'
print(res)

==============================列表推导式
------------------1:引子
生一筐鸡蛋
egg_list=[]
for i in range(10):
egg_list.append('鸡蛋%s' %i)

egg_list=['鸡蛋%s' %i for i in range(10)] #列表解析

------------------2:语法
[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN
]
类似于
res=[]
for item1 in iterable1:
if condition1:
for item2 in iterable2:
if condition2
...
for itemN in iterableN:
if conditionN:
res.append(expression)

------------------3:优点
方便,改变了编程习惯,声明式编程

------------------4:应用
l1=[3,-4,-1,5,7,9]

[i**i for i in l1]

[i for i in l1 if i >0]

s='egon'
[(i,j) for i in l1 if i>0 for j in s] #元组合必须加括号[i,j ...]非法

==============================生成器表达式
------------------1:引子
生一筐鸡蛋变成给你一只老母鸡,用的时候就下蛋,这也是生成器的特性
egg_list=[]
for i in range(10):
egg_list.append('鸡蛋%s' %i)

chicken=('鸡蛋%s' %i for i in range(10))
>>> chicken
<generator object <genexpr> at 0x10143f200>
>>> next(chicken)
'鸡蛋5'

------------------2:语法
语法与列表推导式类似,只是[]->()

(expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN
)

------------------3:优点
省内存,一次只产生一个值在内存中

------------------4:应用
读取一个大文件的所有内容,并且处理行
f=open('a.txt')
g=(line.strip() for line in f)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python