dawn-liu

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

本文档主要内容:

一 装饰器函数的信息打印

二 迭代器

三 生成器

四 生成器表达式和列表推导式

五 内置函数

一 装饰器函数的信息打印

一个函数一旦被装饰器给装饰后,这个函数的信息使用原来的命令打印的就是装饰器函数的信息了,如何改为被装饰函数的信息呢?

from functools import wraps

def logger(f):
    @wraps(f)
    def inner(*args, **kwargs):
        """
        :param args: 函数名,密码
        :param kwargs: 备用
        :return:  True
        """
        ret = f(*args, **kwargs)
        return ret
    return inner

@logger
def login(username,password):
    """
    此函数是完成登录功能的函数,需要用户名,和密码两个参数,返回True 登陆成功
    :return:  True
    """
    print(666)
    return True
# login(1,2)  #inner()
# # login('alex', 123)
print(login.__doc__)
print(login.__name__)

打印结果为:
此函数是完成登录功能的函数,需要用户名,和密码两个参数,返回True 登陆成功
:return: True

login
View Code

二 迭代器

2.1  可迭代对象

定义:在对象中,含有__iter__方法的就是可迭代对象,遵循迭代协议,可迭代对象有:str,list,tuple,dict,set ,range,文件句柄

判断一个对象是否可迭代:int对象不是可迭代对象

1  ‘__iter__' in dir(对象) 例如:print('__iter__' in dir(str))

2 isinstance('abc',Iterable)

例如:

from collections import Iterable
print(isinstance('abc',Iterable))

2.2 迭代器

定义:内部含有__iter_并且含有__next__方法的对象就是迭代器,遵循迭代器协议

转化:可迭代对象转化成迭代器

例如:s='abc'

obj_s=s1.__iter__()   或者  obj_s=iter(s)   

判断一个对象是不是迭代器

1  __iter__ 和 __next__

例如:

s='abc'

print('__iter__' in dir(s))

print('__next__' in dir(s))

2 isinstance('对象',Iterator)
View Code

例如:

from collections import Iterator

l1=[1,2,3]

l1_obj=l1.__iter__()

print(isinstance(l1_obj,Iterator))
View Code

迭代器的取值:

print(obj_s.__next__())
print(obj_s.__next__())
print(obj_s.__next__())
print(obj_s.__next__())  #取完值后这里会报错

 

迭代器的好处:

1,节省内存  2,惰性机制(next一次读一次)    3,单向不可逆

三 生成器

生成器是自定义的迭代器(自己用python代码写的迭代器),函数中见到yield的就是生成器

例如:

def func1():

  print(111)

  yield 666

g_obj=func1()  #生成器对象

print(g_obj)   # <generator object func1 at 0x0000000001E21E60>

print(g_obj.__next__())  #取值
View Code

生成器两种方法的区别  send和next

1 send和next都是对生成器取值

2 send会给上一个yield发送一个值

3 send不能用在第一次取值

4 最后一个yield不能得到值
View Code

四 生成器表达式和列表推导式

一般就几种列表推导式:

1 [变量(加工后的变量) for 变量 in iterable]   ---》 遍历模式

2 [变量(加工后的变量) for 变量 in iterable if 条件]  --》筛选模式

列表推导式和生成器表达式区别

1.把列表解析的[]换成()得到的就是生成器表达式

2.列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
View Code

下面是几个例子:

l = ['您好', '3.64',
'请问您是xxx同学的家长吗', '6.25',
'是的有什么事情吗', '6.15',
'您好我是学大教育的x老师', '5.06',
'这次给给您打电话主要是想了解一下孩子上学期的协议情况', '5.86',
'针对于上学期的学习状况', '5.37',
'我们学校邀请您和孩子周末过来听一下针对性的辅导课好吧好吧', '5.36',
'可以我想问一下都有什么课程呢', '5.65',
'呃主要是有英语和语文', '4.35',
 '你看', '3.77',
 '到时候咱们再联系好吧', '6.10',
 '好的', '6.45',
 '恩再见', '4.84']
# 上面这个列表帮我转成下面这种格式
# [{"onebest":"您好", "speed":"6.060606"},
# {"onebest":"我这是中国电信的客户代表请问您是幺五幺幺零幺五六六六幺号码的长期使用者吗", "speed":"5.479452"},
# {"onebest":"是的", "speed":"5.405406"},
# {"onebest":"为啥谢谢您长期以来的支持",  "speed":"5.529954"},
# {"onebest":"交银退掉", "speed":"4.938272"},
# {"onebest":"考虑了解生活小贴士服务美元四月","speed":"4.672897"},
# {"onebest":"你们可以收到天气情况活动", "speed":"5.529954"},
# {"onebest":"我建议", "speed":"4.347826"},
# {"onebest":"生活中了就是周转现在开通后","speed":"4.024768"},
# {"onebest":"发到您的", "speed":"8.510638"},
# {"onebest":"都会","speed":"4.255319"},
# {"onebest":"现在","speed":"6.451613"},
# {"onebest":"可以享有就是看吗", "speed":"5.161290"},
# {"onebest":"可以","speed":"6.451613"},
# {"onebest":"改天先生那是的",  "speed":"4.046243"},
# {"onebest":"另外再见",  "speed":"5.479452"}
# ]
# print([{"onebest":l[i],"speed":l[i+1]} for i in range(len(l)) if i % 2 == 0])  #通过过滤掉奇数位,在剩下的偶数位来创建
View Code

 另外一个例子:

有下面字典,得到购买每只股票的总价格,并放在一个迭代器中。

结果:list一下[9110.0, 27161.0,......]

portfolio=[
        {'name':'IBM','shares':100,'price':91.1},
        {'name':'AAPL','shares':50,'price':543.22},
        {'name':'FB','shares':200,'price':21.09},
        {'name':'HPQ','shares':35,'price':31.75},
        {'name':'YHOO','shares':45,'price':16.35},
        {'name':'ACME','shares':75,'price':115.65}]
list=[]
b=map(lambda x:x['shares']*x['price'],portfolio)
for i in b:
    list.append(i)
print(list)

或者:

m = map(lambda y:y["shares"]*y["price"],portfolio)
print(list(m))

还是上面的字典,用filter过滤出单价大于100的股票。

b=filter(lambda x:x['price']>100,portfolio)
print(list(b))
View Code

对例子增加一点难度

portfolio=[
        {'name':'IBM','shares':100,'price':91.1},
        {'name':'AAPL','shares':50,'price':543.22},
        {'name':'FB','shares':200,'price':21.09},
        {'name':'HPQ','shares':35,'price':31.75},
        {'name':'YHOO','shares':45,'price':16.35},
        {'name':'ACME','shares':75,'price':115.65}]

li=[{portfolio[i]['name']:portfolio[i]['shares']*portfolio[i]['price']} for i in range(len(portfolio))]
print(li) #[{'IBM': 9110.0}, {'AAPL': 27161.0}, {'FB': 4218.0}, {'HPQ': 1111.25}, {'YHOO': 735.7500000000001}, {'ACME': 8673.75}]
res=filter(lambda x:list(x.values())[-1]>2000,li) #过滤出大于2000d的字典
print(list(res)) #[{'IBM': 9110.0}, {'AAPL': 27161.0}, {'FB': 4218.0}, {'ACME': 8673.75}]

kk=sorted(li,key=lambda x:list(x.values())[-1],reverse=True) #按照总数从大到小排列
print(kk)  #[{'AAPL': 27161.0}, {'IBM': 9110.0}, {'ACME': 8673.75}, {'FB': 4218.0}, {'HPQ': 1111.25}, {'YHOO': 735.7500000000001}]

#需用到下面的解析
s={'a':111}
print(list(s.values())[-1]) #111
View Code

五 内置函数

5.1 eval 执行含有字符串的代码,并返回最终结果

print(eval('2+2'))  --.>结果为4

5.2 exec 执行字符串类型的代码

s = '''
for i in [1,2,3]:
    print(i)
'''
exec(s)
View Code

一般情况eval就是一个表达式,而exec可以执行多条语句

5.3 dir 查看内置属性

5.4 slice用于构造一个切片对象,注意字典和集合不可以使用

li = ['a','b','c','d','e','f','g']
sli_obj = slice(3)
print(li[sli_obj])  #['a','b','c']
View Code

5.5 bytearry:返回一个新字节数组。这个数组里的元素是可变的,并且每个元素的值范围: 0 <= x < 256。

ret = bytearray('alex',encoding='utf-8')
print(id(ret))
print(ret)
print(ret[0])
ret[0] = 65 #改变第一个字母的值
print(ret)
print(id(ret))
结果为:
2116889904496
bytearray(b'alex')
97
bytearray(b'Alex')
2116889904496
View Code

5.6  all:可迭代对象中,全都是True才是True

  any:可迭代对象中,有一个True 就是True

5.7 匿名函数 lambda

函数名 = lambda 参数 :返回值

5.8 函数里面可以有key的函数 min max sorted map filter

 

posted on 2018-06-11 12:09  dawn-liu  阅读(179)  评论(0编辑  收藏  举报