python第四天

名称空间和作用域
作用域即范围
     - 全局范围:全局存活,全局有效
     - 局部范围:临时存活,局部有效
- 作用域关系是在函数定义阶段就已经固定的,与函数的调用位置无关,如下
      x=1
      def f1():
      def f2():
      print(x)
      return f2

      def f3(func):
      x=2
      func()

      f3(f1())


查看作用域:globals(),locals()

global
nonlocal


LEGB 代表名字查找顺序: locals -> enclosing function -> globals -> __builtins__
locals 是函数内的名字空间,包括局部变量和形参
enclosing 外部嵌套函数的名字空间(闭包中常见)
globals 全局变量,函数定义所在模块的名字空间
builtins 内置模块的名字空间
闭包:内部函数包含对外部作用域而非全局作用域的引用
 闭包的意义:返回的函数对象,不仅仅是一个函数对象,在该函数外还包裹了一层作用域,这使得,该函数无论在何处调用,优先使用自己外层包裹的作用域
应用领域:延迟计算(原来我们是传参,现在我们是包起来)
  from urllib.request import urlopen

def index(url):
def get():
return urlopen(url).read()
return get

baidu=index('http://www.baidu.com')
print(baidu().decode('utf-8'))
 装饰器(闭包函数的一种应用场景)
1 为何要用装饰器:
开放封闭原则:对修改封闭,对扩展开放

2 什么是装饰器
装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
装饰器语法:
被装饰函数的正上方,单独一行
@deco1
@deco2
@deco3
def foo():
pass
装饰器补充:wraps
from functools import wraps

def deco(func):
    @wraps(func) #加在最内层函数正上方
    def wrapper(*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

@deco
def index():
    '''哈哈哈哈'''
    print('from index')

print(index.__doc__)


迭代器
迭代的概念:重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值
# while True: #只满足重复,因而不是迭代
# print('====>')

#迭代
l=[1,2,3]
count=0
while count < len(l): #只满足重复,因而不是迭代
print('====>',l[count])
count+=1


为何要有迭代器?
可迭代的对象?
哪些是可迭代对象?
迭代器?
l={'a':1,'b':2,'c':3,'d':4,'e':5}
i=l.__iter__() #等于i=iter(l)

print(next(i))
print(next(i))
print(next(i))
StopIteration?

for循环

迭代器的优缺点:
优点:
提供统一的且不依赖于索引的迭代方式
惰性计算,节省内存
缺点:
无法获取长度
一次性的,只能往后走,不能往前退

迭代器协议
生成器
yield:
把函数做成迭代器
对比return,可以返回多次值,挂起函数的运行状态
三元表达式,列表推导式,生成器表达式

==============================#三元表达式
name='alex'
name='linhaifeng'
res='SB' if name == 'alex' else 'shuai'
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)


list(g) #因g可迭代,因而可以转成列表

==============================声明式编程
文件a.txt内容
apple 10 3
tesla 100000 1
mac 3000 2
lenovo 30000 3
chicken 10 3

 

f=open('a.py')
#求花了多少钱
g=(line.split() for line in f)

sum(float(price)*float(count) for _,price,count in g)


模拟数据库查询
>>> f=open('a.txt')
>>> g=(line.split() for line in f)
>>> goods_l=[{'name':n,'price':p,'count':c} for n,p,c in g]

过滤查询
>>> goods_l=[{'name':n,'price':p,'count':c} for n,p,c in g if float(p) > 10000]

posted @ 2017-07-26 11:12  我是一条小青龙小青龙  阅读(138)  评论(0)    收藏  举报