15 迭代器、生成器、模块和包

第16节 迭代器、生成器


 

作业解答


import os
​
if not os.path.exists('my_tesr.txt'):   # 判断文件是否存在
    file = open('my_test.txt', 'w+', encoding='utf-8')
    
    try:
        my_dict = {'name': 'xiaojiu'}
        file.write(my_dict['name'])
        
    except Exception as e:
        print(e)
        
    finally:
        file.close()
        print('文件正常关闭')
        
# 文件存在则不会运行try 

一, 推导表达式

1,列表推导
  • 循环添加:

    >>> li = []
    >>> for i in range(10):
    ...     li.append(i)
    ... 
    >>> li
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  • 列表推导:

    li = [i for i in range (10)]
  • 列表推导+条件判断:

    li2 = [i for i in range(10) if i % 2 == 0]
  • 列表推导+三目运算:

    li3 = [i if i % 2 == 0 else 0 for i in range(10)]
2,集合和字典推导
  • 集合推导:

    se = {i for i in range(10)}
  • 字典推导:

    li = [1,2,3,4,5,6,7,8,9,10]
    di = {i:j for i, j in enumerate(li)}

二,生成器

1,创建生成器的两种方法
  • 列表推导式的[]改成()
    >>> tu = (i for i in range(1,11))
    >>> next(tu)
    1
    >>> next(tu)
    2
    >>> next(tu)
    3
  • 在函数里面加上 yield
    >>> def func(num):
        a = 0
        while a < num:
            yield a
            a += 1>>> b = func(10)
    >>> next(b)
    0
    >>> next(b)
    1
    >>> next(b)
    2
2, yield运行规则
  • yield 一个对象:返回这个对象、暂停这个对象、等待下次next重新激活

  • 注意:

    yield表达式只能在函数中使用,在函数体中使用yield 表达式可以使函数成为一个生成器

    yield 可以返回表达式结果,并且暂定函数执行,直到next激活下一个yield

Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果,从而节省大量的空间,这也是生成器的主要好处

三,迭代器

1,区分可迭代对象和迭代器
  • 可迭代对象: Iterable

    可迭代对象能用for循环进行遍历

    可以使用 isinstance() 判断一个对象是否是 Iterable 对象

    >>> from collections import Iterable,Iterator
    >>> li = [1,2,3,4,5]
    >>> isinstance(li,Iterable)
    True
    >>> di = {'a':1,'b':2}
    >>> isinstance(di,Iterable)
    True
  • 迭代器: Iterator

    迭代器不仅可以通过for进一行遍历,可以通过next取值

    可以使用 isinstance() 判断个对象是否是 Iterator对象

    >>> from collections import Iterable,Iterator
    >>> li = [1,2,3,4,5]
    >>> li1 = iter(li)
    >>> isinstance(li1,Iterator)
    True
    >>> tu = (1,2,3,4,5)
    >>> isinstance(tu,Iterator)
    False
2,迭代

for 迭代变量 in 可迭代对象,每一次循环都会自动让“迭代变量”指向“下一个元素” 。

# 例1
li = [1,2,3,4,5]
for i in li:
    print(i)
# 例2
li = [1,2,3,4,5]
index = 0
var = None
while index < len(li):
    var = li[index]
    print(var)
    index += 1
    
两次打印结果都一样:
1
2
3
4
5
3,for实现原理
li = [1,2,3,4,5]
li2 = iter(li)
try:
    while True:
        var = next(li2)
        print(var)
​
except StopIteration:
    pass
    
打印结果:
1
2
3
4
5
4,从可迭代对象生成一个迭代器

迭代器 = iter(可迭代对象)

下个值 = next(迭代器)

5,自定义迭代器

迭代器对象本身需要支持以下两种方法,它们一起构成迭代器协议:

iterator.__iter__()
​
iterator.__next__()

取值:

next(iterator)
​
iterator.__next__()

注意:如果迭代器值取完之后,会返回StopIteration 错误

四,模块

1,模块的导入
  • 在python中,模块就是一个py文件,可以使用下面两种方法导入

    import datetime
    
    from datetime import datetime (as this_datetime)
    
    注意:datetiame是一个常用的时间处理模块
  • 在同一目录下,可直接使用上面两种方法去导入

    在不同目录下,需要使用 sys.path 添加路径sys.path.append('path')

  • import sys
    sys.path.append('/home/pyvip/pycharm/学员信息管理系统')
    import zcm
    zcm.func1()
    zcm.func2()
  • 在python3中导入后,会在当前路径下生成一个pycache 文件夹

2,导入语法 与 导入路径
  • import 模块名

    直接导入

    使用时模块名.函数名()

  • import 模块名 as 新名字

    导入以后,重新命名

    使用新名字.函数名()

  • from 模块名 import 函数名

    部分导入,导入模块内部的东西,而不要模块可以在模块里用一个变量 __all__控制被导入函数

    __all__ = ['func1','func2']
    
    def func1():
        print('这是第一行')
    def func2():
        print('这是第二行')
    def func3():
        print('这是第三行')
    from zcm import *
    
    func1()
    func2()
    
    打印结果:
    这是第一行
    这是第二行
3,if __name__ == '__main__'
  • __name__

    python会自动的给模块加上这个属性

    如果模块是被直接调用的,则__name__ 的值是__main__

    否则就是该模块的模块名

  • if __name__ == '__main__'

    该语句可以控制代码在被其他模块导入时不被执行

    def func1():  
        print('这是第一行')
    def func2():
        print('这是第二行')
    def func3():
        print('这是第三行')
        
        
    if name == 'main':
        print('不想被调用')
    import zcm
    zcm.func1()
    
    打印结果:
    这是第一行

五,包和包管理

1,包概念:

把很多模块放到一个文件夹里面,就可以形成一个包

导包

import test.zcm
test.zcm.func1()
​
import test.zcm as t    # test是文件夹,zcm是py文件
t.func1()
​
from test import zcm
zcm.func1()
​
from test import zcm as t
t.func1()

导入全部包 *

__all__ = ['zcm']       # 这句代码必须要写到init里面

from test import *
zcm.func1()
导入包方法:
# 例子1
# 在包里面的 __init__文件里定义函数方法
def initfunc():
    print('这是initfunc')
# 例子1
import pp        # pp是包文件夹的名字
pp.initfunc()

打印结果:
这是initfunc

 

# 例子2
# 在包里面的 __init__文件里定义函数方法
__all__ = ['initfunc']

def initfunc():
    print('这是initfunc')
# 例子2
form pp import *

initfunc()

打印结果:
这是initfunc
2,包管理:

当把很多模块放在文件中时,为了方便引用包中的模块,引入了包管理

3,__init__.py

在包管理中,加入此模块,则包名可以直接通过属性访问的方式,访问此模块内的对象,文件内容可以为空

4,相对路径导入

在包管理中,可以通过. (一个点) 和 .. (两个点)分别来导入同层和上一层的模块

 

posted @ 2018-05-31 00:23  开心每一天q  阅读(150)  评论(0编辑  收藏  举报