博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python函数、装饰器、迭代器、生成器
阅读量:4503 次
发布时间:2019-06-08

本文共 30799 字,大约阅读时间需要 102 分钟。

目录:

  • 函数补充进阶
    • 函数对象
    • 函数的嵌套
    • 名称空间与作用域
    • 闭包函数
  • 函数之装饰器
  • 函数之迭代器
  • 函数之生成器
  • 内置函数

一、函数补充进阶

  1、函数对象: 

函数是第一类对象,即函数可以当作数据传递,它的应用形式也被称为高阶函数,函数的特性如下:

a. 可以被引用

1 # def foo(): 2 #     print('from foo') 3 # 4 # func = foo 5 # print(foo)  # 不加括号为foo函数的内存地址 6 # print(func)  # func指向foo内存地址 7 # func()      # foo内存地址,加()执行 8 ''' 9 结果:10 
11
12 from foo13 '''
View Code

b. 可以当作参数传递

1 # def foo(): 2 #     print('from foo') 3 # 4 # def bar(func): 5 #     print(func) 6 #     func() 7 # 8 # bar(foo) # foo函数内存地址被当作参数传递到bar函数中,并调用 9 10 '''11 结果:12 
13 from foo14 '''
View Code

c. 返回值可以是函数

1 # def foo(): 2 #     print('from foo') 3 # 4 # def bar(func): 5 #     return func 6 # 7 # f = bar(foo)  # 去到返回值foo内存地址 8 # print(f) 9 # f()  # 调用10 11 '''12 结果:13 
14 from foo15 '''
View Code

d. 应用

1 # def select(sql): 2 #     print('----〉select:%s' % sql) 3 # 4 # def insert(sql): 5 #     print('----〉insert:%s' % sql) 6 # 7 # def update(sql): 8 #     print('----〉update:%s' % sql) 9 #10 # def delect(sql):11 #     print('----〉delect:%s' % sql)12 #13 # sql_dic = {
14 # 'select':select,15 # 'delect':delect,16 # 'insert':insert,17 # 'update':update18 # }19 # def main():20 # while True:21 # sql = input('sql>>>').strip()22 # if not sql:continue23 # sql_l = sql.split(' ')24 # if sql_l[0] in sql_dic:25 # sql_dic[sql_l[0]](sql_l)26 #27 # main()28 '''29 结果:30 sql>>>select * form fafafa31 ----〉select:['select', '*', 'form', 'fafafa']32 sql>>>insert * faormafa faf a33 ----〉insert:['insert', '*', 'faormafa', '', 'faf', 'a']34 sql>>>35 '''
View Code

 

  2、函数的嵌套

闭包函数基础

a. 函数的嵌套定义: 函数的嵌套定义:顾名思义就是函数里面,套函数。应用如闭包、装饰器

1 ''' 2   函数的嵌套定义:顾名思义就是函数里面,套函数。应用如闭包、装饰器 3 ''' 4 # 层层调用,层层执行 5 # def f1(): 6 #     def f2(): 7 #         print('from f2') 8 #         def f3(): 9 #             print('from f3')10 #         f3()11 #     f2()12 # f1()13 '''14 结果:15 from f216 from f317 '''
View Code

b. 函数的嵌套调用:属于面向过程(分子原子级操作),细分问题

1 ''' 2   函数的嵌套调用 3 ''' 4 # 判断两个数数字的大小 5 # def max2(x,y): 6 #     return x if x > y else y 7  8 # 判断4个数大小,调用上面的函数 9 # def max4(a,b,c,d):10 #     res1=max2(a,b)11 #     res2=max2(res1,c)12 #     res3=max2(res2,d)13 #     return res314 #15 # print(max4(10,99,31,22))16 '''17 结果:18 9919 '''
View Code

 

  3、名称空间与作用域

a. 名称空间定义(namespace): 名称与对象之间的关系,可以将命名空间看做是字典,其中的键是名称,值是对象

1 ''' 2 1、名称空间定义(namespace): 名字绑定值时,名字与值得对应关系的存放位置为名称空间 3    定义名字的方法 4 ''' 5 # a.导入模块 6 # import time 7 # b.变量赋值 8 # name='egon' 9 # c.函数定义10 # def func():11 #     pass12 # d.类定义(面向对象)13 # class Foo:14 #     pass
View Code

b. 名称空间的分类:

1.内置名称空间:随着python解释器的启动而产生

1 # print(sum) 2 # print(max) 3 # print(min) 4 # 等等,python已启动,初始定义的功能。 5 ''' 6 结果: 7 
8
9
10 '''11 12 # print(max([1,2,3]))13 14 # builtins dir()函数接受模块名作为参数,返回一个排好序的字符串列表,内容是一个模块里定义过的名字。15 # import builtins16 # dir 对象的内建名称空间17 # for i in dir(builtins):18 # print(i)
View Code

2.全局名称空间:文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放入改空间

1 # 不在函数和类,定义变量 2 # x=1 3 # if x ==1 : 4 #     y=2 5  6 # 不在函数和类,导入模块 7 # import time 8  9 # 不在函数和类,定义变量10 # name='egon'11 12 # 不在类中,定义的函数名13 # def func():14 #     pass15 16 # 不在类中,定义类名17 # class Foo:18 #     pass19 20 # x=121 # def func():22 #     money=200023 #     x=224 #     print(func)25 # # 局部x=2 没有调到26 # print(x)27 # # 取到内存地址28 # print(func)29 # # 执行函数可以调到全局变量30 # func()31 # # print(money)  # money属于局部变量,调用不了
View Code

3.局部名称空间:调用函数时会产生局部名称空间,只在函数调用时临时绑定,调用结束解绑定

1 # x=100002 # def func():3 # x = 1 局部变量4 #     x=15 #     def f1():6 #         pass
View Code

 

c. 作用域:为名称空间的具体应用。他们之间的关系,如下对应:

1.全局作用域:内置名称空间,全局名层空间

2.局部作用:局部名称空间

d. 作用于的优先级顺序:局部名称空间---》全局名层空间---》内置名称空间

1 ''' 2 # 后生效 3 # x=1 4 # def func(): 5 #     # 优先生效 6 #     x = 2 7 #     print(x) 8 #     sum = 123123 9 #     print(sum)10 # func()11 '''12 结果:13 214 12312315 '''16 17 # x = 118 # def func():19 #     x=220 #21 # func()22 #23 # print(x)24 '''25 结果:26 127 '''
View Code

 

1.查看全局作用域内的名字:gloabls()

2.查看局局作用域内的名字:locals()

1 ''' 2     查看全局作用域内的名字:gloabls() 3     查看局部作用域内的名字:locals() 4 ''' 5 x=1000 6 def func(): 7     x=2 8     # 全局作用域内 9     print(globals())10     # 局部作用域11     print(locals())12 func()13 # 全局作用域内14 print(globals())15 # 局部作用域16 print(locals())17 # 在全局环境中,locals()和globals()是一样的,但是在局部环境中,就不一样了18 print(globals() is locals())19 '''20 结果:21 {'__name__': '__main__', '__doc__': '\n名称空间与作用域\n1、名称空间定义(namespace): 名称与对象之间的关系,可以将命名空间看做是字典,其中的键是名称,值是对象\n2、名称空间的分类: \n    内置名称空间:随着python解释器的启动而产生\n    全局名称空间:文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放入改空间\n    局部名称空间:调用函数时会产生局部名称空间,只在函数调用时临时绑定,调用结束解绑定\n3、作用域:为名称空间的具体应用。他们之间的关系,如下对应:\n    全局作用域:内置名称空间,全局名层空间\n    局部作用:局部名称空间\n4、作用于的优先级顺序:局部名称空间---》全局名层空间---》内置名称空间\n    查看全局作用域内的名字:gloabls()\n    查看局局作用域内的名字:locals()\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000D9A5DCB160>, '__spec__': None, '__annotations__': {}, '__builtins__': 
, '__file__': 'D:/old_boy/old_boy_17_04/名称空间与作用域.py', '__cached__': None, 'x': 1000, 'func':
}22 {'x': 2}23 {'__name__': '__main__', '__doc__': '\n名称空间与作用域\n1、名称空间定义(namespace): 名称与对象之间的关系,可以将命名空间看做是字典,其中的键是名称,值是对象\n2、名称空间的分类: \n 内置名称空间:随着python解释器的启动而产生\n 全局名称空间:文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放入改空间\n 局部名称空间:调用函数时会产生局部名称空间,只在函数调用时临时绑定,调用结束解绑定\n3、作用域:为名称空间的具体应用。他们之间的关系,如下对应:\n 全局作用域:内置名称空间,全局名层空间\n 局部作用:局部名称空间\n4、作用于的优先级顺序:局部名称空间---》全局名层空间---》内置名称空间\n 查看全局作用域内的名字:gloabls()\n 查看局局作用域内的名字:locals()\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000D9A5DCB160>, '__spec__': None, '__annotations__': {}, '__builtins__':
, '__file__': 'D:/old_boy/old_boy_17_04/名称空间与作用域.py', '__cached__': None, 'x': 1000, 'func':
}24 {'__name__': '__main__', '__doc__': '\n名称空间与作用域\n1、名称空间定义(namespace): 名称与对象之间的关系,可以将命名空间看做是字典,其中的键是名称,值是对象\n2、名称空间的分类: \n 内置名称空间:随着python解释器的启动而产生\n 全局名称空间:文件的执行会产生全局名称空间,指的是文件级别定义的名字都会放入改空间\n 局部名称空间:调用函数时会产生局部名称空间,只在函数调用时临时绑定,调用结束解绑定\n3、作用域:为名称空间的具体应用。他们之间的关系,如下对应:\n 全局作用域:内置名称空间,全局名层空间\n 局部作用:局部名称空间\n4、作用于的优先级顺序:局部名称空间---》全局名层空间---》内置名称空间\n 查看全局作用域内的名字:gloabls()\n 查看局局作用域内的名字:locals()\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000D9A5DCB160>, '__spec__': None, '__annotations__': {}, '__builtins__':
, '__file__': 'D:/old_boy/old_boy_17_04/名称空间与作用域.py', '__cached__': None, 'x': 1000, 'func':
}25 True26 '''
View Code

 

  4、闭包函数

函数嵌套的一种方式,必须遵守以下规则:

a. 定义在内部函数

b. 包含对外部作用域而非全局作用域的引用,该内部函数就成为闭包函数

1 # 定义实例,对象隐藏,全局不可见 2 # def f1(): 3 #     # x内部隐藏,全局不可见 4 #     x = 1 5 #     def f2(): 6 #         print(x) 7 # 8 #     return f2 9 #10 # f=f1()11 # # print(f)12 # # x因为隐藏,所以全局作用域无效13 # x=10000000000000000000000000014 # f()15 '''16 结果:17 118 '''
View Code

 

闭包应用:惰性计算

1 # 爬网页,老式方法 2 # res=urlopen('http://crm.oldboyedu.com').read() 3 # print(res.decode('utf-8')) 4 # from urllib.request import urlopen 5  6 # def index(url): 7 #     def get(): 8 #         return urlopen(url).read() 9 #     return get10 11 # 存在内存里12 # oldboy=index('http://crm.oldboyedu.com')13 # 什么时候想用,什么时候用14 # print(oldboy().decode('utf-8'))15 16 # 闭包函数相对与普通函数会多出一个__closure__的属性,里面定义了一个元组用于存放所有的cell对象,17 # 每个cell对象一一保存了这个闭包中所有的外部变量18 # print(oldboy.__closure__[0].cell_contents)19 20 21 22 23 24 # def f1():25 #     x = 126 #     y = 227 #     def f2():28 #         print(x,y)29 #     return f230 #31 # a = f1()32 # # a()33 # print(a.__closure__[1].cell_contents)34 '''35 结果:36 237 '''
View Code

 

二、函数之装饰器

装饰器:修饰别人的工具,修饰添加功能,工具指的是函数

装饰器本身可以是任何可调用对象,被装饰的对象也可以是任意可调用对象
为什么要用装饰器?

a. 开放封闭原则:对修改是封闭的,对扩展是开放的

b. 装饰器就是为了在不修改被装饰对象的源代码以及调用方式的前提下,为期添加新功能

1、装饰器的基本写法

1 ''' 2 1、装饰器的基本写法 3 ''' 4 # import time 5 # 6 # def timmer(func): 7 #     def wrapper(): 8 #         # 在运行函数前执行,time.time()为当前时间(格林威治时间1970到现在的秒数) 9 #         start_time = time.time()10 #         # 被装饰函数执行,没有返回值,默认为11 #         res = func()12 #         # 在函数运行后执行13 #         stop_time = time.time()14 #         print('run time is %s' %(stop_time-start_time))15 #     return wrapper16 #17 # @timmer  # index = timmer(index)18 # def index():19 #     time.sleep(3)20 #     print('welcome to index')21 #22 # index() # wrapper(index) ---> index()23 '''24 结果:25 welcome to index26 run time is 3.00037980079650927 '''
View Code

2、多实例添加,及传参数函数

1 ''' 2 2、多实例添加,及传参数函数 3 ''' 4 # import time 5 # def timmer(func): 6 #     # 传递参数,保证通用性,应为可变长参数(*args,**kwargs),可接受所有类型的实参 7 #     def wrapper(*args,**kwargs): 8 #         start_time=time.time() 9 #         # 传递参数,保证通用性,应为可变长参数(*args,**kwargs),可接受所有类型的实参10 #         # 有返回值,存值11 #         res=func(*args,**kwargs)12 #         stop_time=time.time()13 #         print('run time is %s' %(stop_time-start_time))14 #         # 有返回值,返回15 #         return res16 #     return wrapper17 #18 # @timmer #index=timmer(index)19 # def index():20 #     time.sleep(3)21 #     print('welcome to index')22 #     # 有返回值,定义23 #     return 124 #25 # #再次调用指需要加@timmer26 # @timmer27 # def foo(name):28 #     time.sleep(1)29 #     print('from foo')30 #31 # # 有返回值,传值打印32 # res=index() #wrapper()33 # print(res)34 #35 # res1=foo('shuyang')  #res1=wrapper('egon')36 # print(res1)37 '''38 运行结果:39 welcome to index40 run time is 3.00038003921508841 142 from foo43 run time is 1.000130891799926844 None45 '''
View Code

3、登录权限,一次登录,多次使用

1 ''' 2 3、登录权限,一次登录,多次使用 3 ''' 4 # 全局,记录用户状态 5 # login_user={'user':None,'status':False} 6 # def auth(func): 7 #     def wrapper(*args,**kwargs): 8 #         # 判断用户状态,有直接返回结果 9 #         if login_user['user'] and login_user['status']:10 #             res=func(*args,**kwargs)11 #             return res12 #         # 否则,继续13 #         else:14 #             name=input('name: ')15 #             password=input('passwd: ')16 #             if name == 'shuyang' and password == '123':17 #                 login_user['user']='shuyang'18 #                 login_user['status']=True19 #                 print('\033[45mlogin successful\033[0m')20 #                 res=func(*args,**kwargs)21 #                 return res22 #             else:23 #                 print('\033[45mlogin err\033[0m')24 #     return wrapper25 #26 # @auth27 # def index():28 #     print('welcome to index page')29 # @auth30 # def home(name):31 #     print('%s welcome to home page' %name)32 # index()33 # home('shuyang')34 35 '''36 结果:37 name: shuyang38 passwd: 12339 login successful40 welcome to index page41 shuyang welcome to home page42 '''
View Code

4、多装饰器,执行顺序

1 ''' 2 4、多装饰器,执行顺序 3 ''' 4 # import time 5 # def timmer(func): 6 #     def wrapper(*args,**kwargs): 7 #         print('timmer--->wrapper') 8 #         start_time=time.time() 9 #         res=func(*args,**kwargs)10 #         stop_time=time.time()11 #         print('run time is %s' %(stop_time-start_time))12 #         return res13 #     return wrapper14 #15 # login_user={'user':None,'status':False}16 # def auth(func):17 #     def wrapper(*args,**kwargs):18 #         print('auth--->wrapper')19 #         if login_user['user'] and login_user['status']:20 #             res=func(*args,**kwargs)21 #             return res22 #         else:23 #             name=input('name: ')24 #             password=input('pwd: ')25 #             if name == 'shuyang' and password == '123':26 #                 login_user['user']='shuyang'27 #                 login_user['status']=True28 #                 print('\033[45mlogin successful\033[0m')29 #                 res=func(*args,**kwargs)30 #                 return res31 #             else:32 #                 print('\033[45mlogin err\033[0m')33 #     return wrapper34 #35 # # 顺序执行36 # @auth  # timmer = auth--->wrapper--->timmer37 # @timmer # index = auth--->wrapper--->timmer--->wrapper(index)38 # def index():39 #     time.sleep(3)40 #     print('welcome to index page')41 #42 # # 顺序执行,调转则timmer包含auth增加了程序执行时间43 # @timmer  # auth = timmer--->wrapper--->auth44 # @auth  # home = timmer--->wrapper--->auth---->wrapper(home)45 # def home(name):46 #     time.sleep(3)47 #     print('%s welcome to home page' %name)48 # index()49 # home('shuyang')50 '''51 结果:52 auth--->wrapper53 name: shuyang54 pwd: 12355 login successful56 timmer--->wrapper57 welcome to index page58 run time is 3.00037813186645559 timmer--->wrapper60 auth--->wrapper61 shuyang welcome to home page62 run time is 3.00038242340087963 '''
View Code

5、有参装饰器

1 ''' 2 5、有参装饰器 3 ''' 4 # login_user={'user':None,'status':False} 5 # 在包一个函数,根据作用域特性传值 6 # def auth(db_tpye): 7 #     def auth2(func): 8 #         def wrapper(*args,**kwargs): 9 #            #传进来了10 #             if db_tpye == 'file':11 #                 if login_user['user'] and login_user['status']:12 #                     res=func(*args,**kwargs)13 #                     return res14 #                 else:15 #                     name=input('name: ')16 #                     password=input('pwd: ')17 #                     if name == 'shuyang' and password == '123':18 #                         login_user['user']='egon'19 #                         login_user['status']=True20 #                         print('\033[45mlogin successful\033[0m')21 #                         res=func(*args,**kwargs)22 #                         return res23 #                     else:24 #                         print('\033[45mlogin err\033[0m')25 #             elif db_tpye == 'ldap':26 #                 print('db_type---->ldap')27 #         return wrapper28 #     return auth229 #30 # @auth('file')31 # def index():32 #     print('welcome to index page')33 #34 # @auth('ldap')35 # def home(name):36 #     print('%s welcome to home page' %name)37 # index()38 # home('shuyang')39 '''40 结果:41 name: shuyang42 pwd: 12343 login successful44 welcome to index page45 db_type---->ldap46 '''
View Code

6、装饰器@functools.wraps

a.官网装饰器定义:

装饰器是一个函数,其主要用途是包装另一个函数或类。这种包装的首要目的是透明地修改或增强被包

装对象的行为。

b.@functools.wraps作用:

因为装饰器是一个闭包函数,怎样能获取被修饰函数的详细信息,如:__name__。

此类实际调用函数的属性。@functools.wraps就提供了该功能。
它是如何实现的,下面的例子是通过反射的原理把func的一些属性更新给了callf函数。原func的属性
不变。但是callf的属性还是跟原func不完全一样,so,如有类似的问题,还需要自己写。
具体,请看未来的类章节。

1 import functools 2 import sys 3 debug_log = sys.stderr 4  5 def trace(func): 6     if debug_log: 7         @functools.wraps(func) 8         def callf(*args, **kwargs): 9             """A wrapper function."""10             debug_log.write('Calling function: {}\n'.format(func.__name__))11             res = func(*args, **kwargs)12             debug_log.write('Return value: {}\n'.format(res))13             return res14         return callf15     else:16         return func17 18 @trace19 def square(x):20     """Calculate the square of the given number."""21     return x * x22 23 if __name__ == '__main__':24     print(square(3))25     print(square.__doc__)26     print(square.__name__)27 '''28 结果:29 Calling function: square30 Return value: 931 932 Calculate the square of the given number.33 square34 35 不加结果@functools.wraps(func):36 Calling function: square37 Return value: 938 939 A wrapper function.40 callf41 '''
View Code

 

三、迭代器

1、迭代的概念:

重复+上一次迭代的结果为下一次迭代的初始值,重复的过程称为迭代,每次重复即一次迭代,并且每次迭代的结果是下一次迭代的初始值

a. 不是迭代器

1 # while True: #只满足重复,因而不是迭代2 #     print('====>')3 4 '''5 结果:6 ====>7 ====>8 ====>9 '''
View Code

b. 迭代while写法

1 # 下面才为迭代 2 # list列表是可迭代对象 3 # l = [1, 2, 3] 4 # count = 0 5 # while count < len(l):  # 只满足重复,因而不是迭代 6 #     print('====>', l[count]) 7 #     count += 1 8 ''' 9 结果:10 ====> 111 ====> 212 ====> 313 '''14 15 # tuple元祖是可迭代对象16 # l = (1, 2, 3)17 # count = 018 # while count < len(l):  # 只满足重复,因而不是迭代19 #     print('====>', l[count])20 #     count += 121 '''22 结果:23 ====> 124 ====> 225 ====> 326 '''27 28 # 字符串是可迭代对象29 # s='hello'30 # count = 031 # while count < len(s):32 #     print('====>', s[count])33 #     count += 134 '''35 结果:36 ====> h37 ====> e38 ====> l39 ====> l40 ====> o41 '''
View Code

  ps.总结:while这种方式,指能迭代有序的对象,那无需的想字典、集合、文件如何操作??

2、为什么要有迭代器?

对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式

1 #有序的2 # [1,2].__iter__()3 # 'hello'.__iter__()4 # (1,2).__iter__()5 #无序的6 # {'a':1,'b':2}.__iter__()7 # {1,2,3}.__iter__()
View Code

 

a. 可迭代的对象:内置__iter__方法的,都是可迭代的对象

b. 迭代器:执行__iter__方法,得到的结果就是迭代器,迭代器对象有__next__方法

1 # 列表,可迭代的对象转迭代器使用 2 # i=[1,2,3].__iter__() 3 # 4 # print(i)  # 打印一个内存地址 5 ''' 6 结果: 7 
8 ''' 9 #10 # print(i.__next__())11 # print(i.__next__())12 # print(i.__next__())13 # print(i.__next__()) #抛出异常:StopIteration14 '''15 结果:16 117 Traceback (most recent call last):18 219 File "D:/old_boy/old_boy_17_04/迭代器.py", line 125, in
20 321 print(i.__next__()) #抛出异常:StopIteration22 StopIteration23 '''24 25 # 字典,可迭代的对象转迭代器使用26 # i={'a':1,'b':2,'c':3}.__iter__()27 #28 # print(i.__next__())29 # print(i.__next__())30 # print(i.__next__())31 # print(i.__next__()) #抛出异常:StopIteration32 '''33 结果:34 Traceback (most recent call last):35 File "D:/old_boy/old_boy_17_04/迭代器.py", line 142, in
36 print(i.__next__())37 StopIteration38 a39 b40 c41 '''42 43 # 字典,可迭代的对象转迭代器使用之异常处理44 # dic={'a':1,'b':2,'c':3}45 # i=dic.__iter__()46 # while True:47 # try:48 # key=i.__next__()49 # print(dic[key])50 # except StopIteration:51 # break52 '''53 结果:54 155 256 357 '''58 59 # 集合,可迭代的对象转迭代器使用60 # __iter__ == iter()61 # s={'a',3,2,4}62 # s.__iter__() #iter(s)63 # i=iter(s)64 # print(next(i))65 # print(next(i))66 # print(next(i))67 # print(next(i))68 # print(next(i))69 '''70 结果:71 Traceback (most recent call last):72 273 File "D:/old_boy/old_boy_17_04/迭代器.py", line 180, in
74 print(next(i))75 376 StopIteration77 478 a79 '''80 81 # ps.字符串,内置函数82 # s='hello'83 # print(s.__len__())84 #85 # print(len(s))86 # 总结:87 # len(s)====== s.__len__()
View Code

 

3、如何判断一个对象是可迭代的对象,还是迭代器对象?

a. 讨论数据对象

1 # 'abc'.__iter__()  # 字符串str2 # ().__iter__()  # 元祖tuple3 # [].__iter__()  # 列表list4 # {'a':1}.__iter__()  # 字典dict5 # {1,2}.__iter__()  # 集合set6 # f = open('a.txt','w') # 文件file7 # f.__iter__()
View Code

b. 可迭代对象:只有__iter__方法,执行该方法得到的迭代器对象。及可迭代对象通过__iter__转成迭代器对象

1 ''' 2     b. 可迭代对象:只有__iter__方法,执行该方法得到的迭代器对象。及可迭代对象通过__iter__转成迭代器对象 3 ''' 4 # 下列数据类型都是可迭代的对象 5 # from collections import Iterable,Iterator 6 # print(isinstance('abc',Iterable)) 7 # print(isinstance([],Iterable)) 8 # print(isinstance((),Iterable)) 9 # print(isinstance({'a':1},Iterable))10 # print(isinstance({1,2},Iterable))11 # f = open('a.txt','w')12 # print(isinstance(f,Iterable))13 '''14 结果:15 True16 True17 True18 True19 True20 True21 '''
View Code

c. 迭代器对象:对象有__next__,对象有__iter__,对于迭代器对象来说,执行__iter__方法,得到的结果仍然是它本身

1 ''' 2     c. 迭代器对象:对象有__next__,对象有__iter__,对于迭代器对象来说,执行__iter__方法,得到的结果仍然是它本身 3 ''' 4 # 只有文件是迭代器对象 5 # from collections import Iterable,Iterator 6 # print(isinstance('abc',Iterator)) 7 # print(isinstance([],Iterator)) 8 # print(isinstance((),Iterator)) 9 # print(isinstance({'a':1},Iterator))10 # print(isinstance({1,2},Iterator))11 # f = open('a.txt','w')12 # print(isinstance(f,Iterator))13 '''14 结果:15 False16 False17 False18 False19 False20 True21 '''
View Code

 

4、可迭代对象通过__iter__转成迭代器对象

a.迭代协议:

对象有__next__
对象有__iter__,对于迭代器对象来说,执行__iter__方法,得到的结果仍然是它本身

1 # 对象有__iter__,对于迭代器对象来说,执行__iter__方法,得到的结果仍然是它本身  2 # f = open('a.txt','r')  3 # f1=f.__iter__()  4 #  5 # print(f)  6 # print(f1)  7 # print(f is f1)  8 '''  9 结果: 10 <_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'> 11 <_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'> 12 True 13 ''' 14  15 # 可迭代对象list,可以看出就是一个迭代器 16 # l=[] 17 # i=l.__iter__() 18 # 19 # print(i.__iter__()) 20 # print(i) 21 # print(l) 22 ''' 23 结果: 24 
25
26 [] 27 ''' 28 29 # dict字典,以前的调用方式 30 # dic={'name':'egon','age':18,'height':'180'} 31 # print(dic.items()) 32 # 33 # for k,v in dic.items(): 34 # print(k,v) 35 ''' 36 结果: 37 dict_items([('name', 'egon'), ('age', 18), ('height', '180')]) 38 name egon 39 age 18 40 height 180 41 ''' 42 43 # dict字典,while迭代器调用 44 # dic={'name':'egon','age':18,'height':'180'} 45 # i=iter(dic) 46 # while True: 47 # try: 48 # k=next(i) 49 # print(k) 50 # except StopIteration: 51 # break 52 ''' 53 结果: 54 name egon 55 age 18 56 height 180 57 ''' 58 59 # for迭代调用 60 # dic={'name':'egon','age':18,'height':'180'} 61 # for k in dic: #i=iter(dic) k=next(i) 62 # print(k) 63 # print(dic[k]) 64 ''' 65 结果: 66 name 67 egon 68 age 69 18 70 height 71 180 72 ''' 73 74 # list的for循环迭代 75 # l=['a','b',3,9,10] 76 # for i in l: 77 # print(i) 78 ''' 79 结果: 80 a 81 b 82 3 83 9 84 10 85 ''' 86 87 # 文件迭代器,直接可以for循环迭代 88 # with open('a.txt','r',encoding='utf-8') as f: 89 # for line in f: 90 # print(line.strip()) 91 ''' 92 结果: 93 1111 94 2222 95 3333 96 4444 97 5555 98 6666 99 7777100 '''
View Code

 

ps.

总结:

python中for就是通过迭代的方式来实现调用的。while只是普通的循环
for迭代 == while + try...except...(异常处理方式)

5、 迭代器的优点和缺点

a.优点:

1. 提供了一种不依赖下标的迭代方式

1 # 提供了一种不依赖下标的迭代方式 2 # l=[10000,2,3,4,5] 3 # i=iter(l) 4 # print(i) 5 # print(next(i)) 6 ''' 7 结果: 8 
9 1000010 '''
View Code

2. 就迭代器本身来说,更节省内存。迭代一个值,原来迭代的值丢弃

b.缺点:

1. 无法获取迭代器对象的长度

2. 不如序列类型取值灵活,是一次性的,只能往后取值,不能往前退

1 # 不如序列类型取值灵活,是一次性的,只能往后取值,不能往前退 2 # f=open('a.txt',encoding='utf-8') 3 # 4 # for line in f.readlines(): 5 #     print(line.strip()) 6 # 7 # print(next(f)) 8 ''' 9 Traceback (most recent call last):10 111111   File "D:/old_boy/old_boy_17_04/迭代器.py", line 398, in 
12 222213 333314 444415 555516 666617 777718 print(next(f))19 StopIteration20 '''21 22 # f=open('a.txt',encoding='utf-8')23 # print(next(f))24 # for line in f:25 # print(line.strip())26 '''27 结果:28 111129 30 222231 333332 444433 555534 666635 777736 '''37 38 39 # 列表迭代40 # l=[10000,2,3,4,5]41 #42 # i=iter(l)43 #44 # for item in i:45 # print(item)46 # print('=============================')47 # for item in i:48 # print(item)49 '''50 结果:51 1000052 253 354 455 556 =============================57 '''
View Code

 

ps. 枚举函数enumerate(),实际也是迭代器

l=[10000,2,3,4,5]

i=enumerate(l)

print(next(i))

print(next(i))

四、函数之生成器

生成器: 只要函数体包含yield关键字,该函数就是生成器函数。

return函数

1 ''' 2 return 3 ''' 4 # def foo(): 5 #     return 1 6 #     return 2 7 #     return 3 8 #     return 4 9 #10 # res1=foo()11 # print(res1)12 #13 # res2=foo()14 # print(res2)15 '''16 结果:17 118 119 '''
View Code

1、生成器就是迭代器

1 ''' 2 1、生成器就是迭代器 3 ''' 4 # def foo(): 5 #     print('first') 6 #     yield 1 7 #     print('second') 8 #     yield 2 9 #     print('third')10 #     yield 311 #     print('fourth')12 #     yield 413 #     print('fifth')14 #15 # g=foo()16 # for i in g:17 #     print(i)18 '''19 结果:20 first21 122 second23 224 third25 326 fourth27 428 fifth29 '''30 # print(g)31 #32 # print(next(g)) #触发迭代器g的执行,进而触发函数的执行33 # print(next(g))34 # print(next(g))35 # print(next(g))36 # print(next(g))37 '''38 结果239 
40 first41 142 second43 244 third45 346 fourth47 448 fifth49 Traceback (most recent call last):50 File "D:/old_boy/old_boy_17_04/生成器.py", line 54, in
51 print(next(g))52 StopIteration53 '''
View Code

2、生成器简单调用

1 ''' 2 2、生成器简单调用 3 ''' 4 # def counter(n): 5 #     print('start...') 6 #     i=0 7 #     while i < n: 8 #         yield i 9 #         i+=110 #     print('end...')11 #12 #13 # g=counter(5)14 # print(g)15 # print(next(g))16 # print(next(g))17 # print(next(g))18 # print(next(g))19 # print(next(g))20 # print(next(g))21 '''22 结果:23 Traceback (most recent call last):24 
25 File "D:/old_boy/old_boy_17_04/生成器.py", line 109, in
26 start...27 print(next(g))28 029 StopIteration30 131 232 333 434 end...35 '''
View Code

3、总结:yield的功能

a. 相当于为函数封装好__iter__和__next__

b. return只能返回一次值,函数就终止了,而yield能返回多次值,每次返回都会将函数暂停,下一次next会从上一次暂停的位置继续执行

4、yield程序实例(tail -f a.txt | grep 'python' 类功能python程序版)

1 #tail -f a.txt | grep 'python' 类功能python程序版 2  3 # import time 4 # def tail(filepath): 5 #     ''' 6 #     tail功能 7 #     :param filepath: 文件路径 8 #     :return: 相当于return文件最后一行,后等待文件输入 9 #     '''10 #     with open(filepath,encoding='utf-8') as f:11 #         '''12 #         seek(offset,whence=0)13 #         offset:开始的偏移量,也就是代表需要移动偏移的字节数14 #         whence:给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,15 #         1代表从当前位置开始算起,2代表从文件末尾算起。默认为016 #         '''17 #         f.seek(0,2)18 #         while True:19 #             line=f.readline().strip()20 #             if line:21 #                 yield line22 #             else:23 #                 time.sleep(0.2)24 #25 # #相当于return文件最后一行,后继续等待next下次调用26 # t=tail('a.txt')27 #28 # # 测试tail功能是否有效29 # # for line in t:30 # #     print(line)31 #32 # def grep(pattern,lines):33 #     '''34 #     grep 功能实现35 #     :param pattern: 校验关键字36 #     :param lines: 要校验的行37 #     :return: 相当于return符合检验的行,后等待行继续调用输入38 #     '''39 #     for line in lines:40 #         if pattern in line:41 #             yield line42 #43 #44 # g=grep('python',tail('a.txt'))45 # #返回内存地址46 # print(g)47 #48 # #迭代输出49 # for i in g:50 #     print(i)
View Code

 

五、内置函数

  

 

1、数学运算

  abs(), round(),pow(),divmod(),max(),min(),sum()

1 ''' 2 1、数学运算 3 ''' 4 # abs(-5)  # 取绝对值,也就是5 5 # round(2.623423, 4)  # 四舍五入取整,也就是3.0, 4为精准到四位四舍五入 6 # pow(2, 3)  # 相当于2**3,如果是pow(2, 3, 5),相当于2**3 % 5 7 # divmod(9, 2)  # 返回除法结果和余数 8 # max([1, 5, 2, 9])  # 求最大值 9 # min([9, 2, -4, 2])  # 求最小值10 # sum([2, -1, 9, 12])  # 求和
View Code

2、工厂函数

  int(), float(), str(), bool(), slice(), list(), tuple(), dict(), set(), frozenset()

1 # int("5")  # 转换为整数 integer 2 # float(2)  # 转换为浮点数 float 3 # str(2.3)  # 转换为字符串 string 4 # bool(0)  # 转换为相应的真假值,在Python中,0相当于False在Python中,下列对象都相当于False:[], (), {}, 0, None, 0.0, '' 5 # slice(5, 2, -1)  # 构建下标对象 slice,切片函数 6 # list((1, 2, 3))  # 转换为表 list 7 # tuple([2, 3, 4])  # 转换为定值表 tuple 8 # dict(a=1, b="hello", c=[1, 2, 3])  # 构建词典 dictionary 9 # set()          创建集合函数10 # frozenset()  创建一个不可修改的集合 如:s=frozenset({1,2}) # 定义不可变集合
View Code

3、类型转换

  ord(), chr(), bin(), hex(), oct(), complex()

1 # ord("A")  # "A"字符对应的数值2 # chr(65)  # 数值65对应的字符3 # bin(56)  # 返回一个字符串,表示56的二进制数4 # hex(56)  # 返回一个字符串,表示56的十六进制数5 # oct(56)  # 返回一个字符串,表示56的八进制数6 # complex(3, 9)  # 返回复数 3 + 9j
View Code

4、序列操作

  all(), any(), sorted(), reversed()

1 # all([True, 1, "hello!"])        # 是否所有的元素都相当于True值2 # any(["", 0, False, [], None])   # 是否有任意一个元素相当于True值3 # sorted([1,5,3])                  # 返回正序的序列,也就是[1,3,5]4 # reversed([1,5,3])               # 返回反序的序列,也就是[3,5,1]
View Code

5、编译执行函数

  repr(), compile(), eval(), exec()

1 # repr(me)                         # 返回一个对象的字符串表示。有时可以使用这个函数来访问操作。 2 # compile("print('Hello')",'test.py','exec')       # 编译字符串成为code对象 3 # eval("1 + 1")                     # 解释字符串表达式。参数也可以是compile()返回的code对象 4 ''' 5 # cmd='print("你瞅啥")' 6 #  7 # dic="{'a':1,'b':2}" 8 # d=eval(dic) 9 # print(type(d),d['a'])10 # 11 # with open('user.db','w',encoding='utf-8') as f:12 #     user_dic={'name':'egon','password':'123'}13 #     f.write(str(user_dic))14 # 15 # with open('user.db','r',encoding='utf-8') as f:16 #     dic=f.read()17 #     print(dic,type(dic))18 #     dic=eval(dic)19 #     print(dic['name'])20 '''21 # exec("print('Hello')")            #  exec()执行字符串或complie方法编译过的字符串,没有返回值
View Code

6、帮助函数

  dir(), help(), id(), len(), challables()

1 ''' 2 6、帮助函数 3 ''' 4 # dir()  不带参数时返回当前范围内的变量,方法和定义的类型列表,带参数时返回参数的属性,方法列表 5 ''' 6 l=[] 7 print(dir(l)) #查看一个对象下面的属性 8 ''' 9 # help()  返回对象的帮助文档10 '''11 print(help(l))12 '''13 # id()  返回对象的内存地址14 '''15 # x=116 # y=x17 # print(id(x),id(y))18 #19 # print(x is y) #判断的是身份20 '''21 # len()  返回对象长度,参数可以是序列类型(字符串,元组或列表)或映射类型(如字典)22 # challable()  判断对象是否可以被调用,能被调用的对象就是一个callables对象,比如函数和带有__call__()的实例23 '''24 def func():25     pass26 print(callable(func))27 '''
View Code

7、作用域查看函数

  globals(), locals(), vars()

1 # globals()  返回一个描述当前全局变量的字典2 # locals()  打印当前可用的局部变量的字典3 # vars()  # 1. 当函数不接收参数时,其功能和locals函数一样,返回当前作用域内的局部变量。4           # 2. 当函数接收一个参数时,参数可以是模块、类、类实例,或者定义了__dict__属性的对象。
View Code

8、迭代器函数

  iter(), next(), enumerate(), range()#python3中为生成一个迭代器

1 ''' 2 8、迭代器函数 3 ''' 4 ''' 5 iter(o[, sentinel]) 6 返回一个iterator对象。该函数对于第一个参数的解析依赖于第二个参数。 7 如果没有提供第二个参数,参数o必须是一个集合对象,支持遍历功能(__iter__()方法)或支持序列功能(__getitem__()方法), 8 参数为整数,从零开始。如果不支持这两种功能,将处罚TypeError异常。 9 如果提供了第二个参数,参数o必须是一个可调用对象。在这种情况下创建一个iterator对象,每次调用iterator的next()方法来无10 参数的调用o,如果返回值等于参数sentinel,触发StopIteration异常,否则将返回该值。11 '''12 # next()  返回一个可迭代数据结构(如列表)中的下一项13 # enumerate()  # 返回一个可以枚举的对象,该对象的next()方法将返回一个元组14 # x=range(10)15 # enumerate([1,2,3]).__next__()16 # range()  根据需要生成一个指定范围的数字,可以提供你需要的控制来迭代指定的次数
View Code

9、其他函数

  hash(), filter(), format(), input(), open(), print(), zip(), map(), __import__

1 # hash() 哈希值用于快递比价字典的键。 2 # 1. 只要校验的内容一致,那hash得到结果永远一样 3 # 2. 不可逆 4 # 3. 只要采用的哈希算法一样,那无论被校验的内容有多长,hash的到的结果长度都一样 5 # print(hash('asdfasdfsadf')) 6 # print(hash('asdfasdfsadf')) 7  8 # filter()  过滤器,构造一个序列,等价于[ item for item in iterables if function(item)],在函数中设定过滤条件,逐一循环迭代器中的元素,将返回值为True时的元素留下,形成一个filter类型数据 9 '''10 filter(function, iterable)11 参数function:返回值为True或False的函数,可以为None。12 参数iterable:序列或可迭代对象。13 >>> def bigerthan5(x):14 ...     return x > 515 >>> filter(bigerthan5, [3, 4, 5, 6, 7, 8])16 [6, 7, 8]17 '''18 19 # format()  #格式化输出字符串,format(value, format_spec)实质上是调用了value的__format__(format_spec)方法20 '''21 "I am {0}, I like {1}!".format("wang", "moon")22 "I am {}, I like {}!".format("wang", "moon")23 "I am {name}, I like {msg}!".format(name = "wang", msg ="moon")24 '''25 26 # input()  #获取用户输入内容27 # open()  打开文件28 # print()  输出函数29 30 # zip()  拉链函数将对象逐一配对31 # s='helloo'32 # l=[1,2,3,4,5]33 #34 # z=zip(s,l)35 # print(z)36 # for i in z:37 #     print(i)38 39 40 # import time41 # m=__import__('time') #以字符串的形式导入模块42 # m.sleep(3000)43 44 '''45 map(function, iterable,...)46 对于参数iterable中的每个元素都应用fuction函数,并将结果作为列表返回。47 如果有多个iterable参数,那么fuction函数必须接收多个参数,这些iterable中相同索引处的元素将并行的作为function函数的参数。48 如果一个iterable中元素的个数比其他少,那么将用None来扩展改iterable使元素个数一致。49 如果有多个iterable且function为None,map()将返回由元组组成的列表,每个元组包含所有iterable中对应索引处值。50 参数iterable必须是一个序列或任何可遍历对象,函数返回的往往是一个列表(list)。51 52 li = [1,2,3]53 data = map(lambda x :x*100,li)54 print(type(data))55 data = list(data)56 print(data)57 58 运行结果:59 60 
61 [100, 200, 300]62 '''
View Code

10、面向对象使用函数

  super(), isinstance(), issubclass(), classmethod(), staticmethod(), proerty(), delatter(), hasattr(), getattr(), setattr()

1 #super()  调用父类的方法 2  3 # isinstance()  检查对象是否是类的对象,返回True或False 4 # issubclass()  检查一个类是否是另一个类的子类。返回True或False 5  6  7 # classmethod()  # 用来指定一个方法为类的方法,由类直接调用执行,只有一个cls参数,执行雷的方法时,自动将调用该方法的类赋值给cls.没有此参数指定的类的方法为实例方法 8 # staticmethod 9 # property10 11 # delattr()  # 删除对象的属性12 # hasattr13 '''14 hasattr(object,name)15 判断对象object是否包含名为name的特性(hasattr是通过调用getattr(object,name))是否抛出异常来实现的。16 参数object:对象17 参数name:特性名称18 >>> hasattr(list, 'append')19 True20 >>> hasattr(list, 'add')21 False22 '''23 #getattr()  获取对象的属性24 #setattr()  与getattr()相对应
View Code

 

转载于:https://www.cnblogs.com/wangshuyang/p/6888144.html

你可能感兴趣的文章
HackerRank "Training the army" - Max Flow
查看>>
jquery next()方法
查看>>
深入剖析js命名空间函数namespace
查看>>
SQLHelper
查看>>
Cocos2d-x 3.0 编译出错 解决 error: expected &#39;;&#39; at end of member declaration
查看>>
Ubuntu12.04下载Repo
查看>>
python基础教程_学习笔记10:异常
查看>>
MATLAB——scatter的简单应用
查看>>
linux下复制粘贴快捷键
查看>>
什么是对象
查看>>
记录开发小程序
查看>>
WinSock服务程序
查看>>
巴西柔术第五课:过腿
查看>>
文件的操作
查看>>
网上图书商城项目学习笔记-007登录功能实现
查看>>
关于mysql的级联删除(之前好多人咨询过我)
查看>>
Linux环境下的C/C+基础调试技术2——程序控制
查看>>
wpf动画同步闪烁
查看>>
3.16上午 复习雅思核心词+新单词100个
查看>>
Html5 部分特性
查看>>