【笔记】Python基础学习(四)

九、Python高级特性

1、迭代器

1.1 认识迭代器

  • 迭代器
    • 迭代类似于循环,提供了迭代方法的容器称为迭代器
  • 可迭代对象
    • 在定义对象时,有__ iter __( )方法的就是可迭代对象
  • 迭代器的核心方法
    • iter( ) 和 next( )方法
    • iter( ) 方法用于创建迭代对象
    • next( ) 方法用于遍历对象的元素
# 迭代器示例
list1 = [1, 2, 3, 4]
print('list1的对象类型:', type(list1))
l = iter(list1)
print('iter(list1)的对象类型:', type(l))
print(next(l))
print(next(l))
print(next(l))
print(next(l))

1.2 自定义迭代器

  • 迭代器类

    • 在类中定义了__ iter __ ( )和__ next __ ( )方法的类
  • 可迭代类

    • 类中的__ iter __( )方法里面使用了自定义的迭代器类实现迭代过程

1.3 迭代器的作用与扩展

  • 使用迭代器的优点

    • 直接循环时将所有数据加载如内存,对内存消耗大
    • 迭代器每次迭代智慧取出当前迭代的数据存储在内存进行读取,上一次迭代的数据会在内存中销毁,并且其他数据不会加载到内存中
    • 在对象存储数据量过大的情况下,迭代器可以节省大量内存开销,提高程序的运行速度
  • 迭代器工具

    • itertools模块提供了丰富的迭代器工具
    • itertools模块提供了近20个迭代器函数,主要分为:
      1. 无限迭代器:永无止尽的输出迭代对象的元素,当对象元素有限是就重复输出
      2. 迭代短序列:通过判断条件进行输出元素
      3. 组合迭代序列:将多个迭代对象的元素按照一定规则进行合并或排序等操作

2、 生成器

2.1 生成器定义

  • 生成器

    • 在Python中,使用了关键字yield的函数被称为生成器
    • 生成器将返回一个迭代器的函数,并且生成器只能用于迭代操作;
  • 协同程序

    • 函数可以暂停或挂起,并在需要的时候从程序离开的地方继续或者重新开始
  • 生成器运行过程

    • 调用生成器运行的过程中,每次执行到关键字yield的时候,函数就会暂停运行,并将关键字yield后面设置的值作为返回值。当下一次执行next( )方法的时候,程序会从当前位置继续运行
# 生成器
def myGen():
    location = 1
    print('location is:', location)
    yield location
    location += 1
    print('location is:', location)
    yield location
    location += 1
    print('location is:', location)
    yield location

2.2 生成器推导式

  • 生成器推导式
    • 生成器推导式是使用小括号表示的,小括号里面的代码与列表推导式的代码相同,以for循环为主,在每次循环中可以使用if语句进行判断
# 创建生成器g
g = (i for i in range(10) if i % 2 == 0)

# 遍历输出生成器g的每个元素
for i in g:
	print(i)

3、装饰器

3.1 装饰器的定义

  • 装饰器
    • 装饰器是为已有的函数方法或类添加新的功能,无须重新定义
    • 装饰器的表示语法是在函数或类的前面添加【 @ 】符号
@decorator
def myDef():
	pass
  • 装饰器的类型
    • 装饰器可以使用函数方法定义,称为函数装饰器
    • 装饰器可以使用类方式定义,称为类装饰器
    • 装饰器可以根据需要设置参数,分为有参装饰器和无参装饰器

3.2 无参数的函数装饰器

  • 闭包
    • 闭包被称为词法闭包或函数闭包;它是引用了自由变量的函数
    • 如果在一个函数内部嵌套了另外一个函数,并且这个内部函数对外部作用域的变量进行了引用,那么这个内部函数称为闭包;根据理解装饰器是一个函数,并且函数里面还定义了一个函数
  • 装饰器的定义过程说明:
    1. 装饰器是以函数方式表达,并且在函数里面又定义了一个函数
    2. 最外层函数设置了参数fun,而内层函数可以调用最外层的函数的参数fun
    3. 参数fun表示被装饰的函数名称,所以内层函数可以调用被装饰的函数
    4. 最外层函数必须使用return设置返回值(返回值为内层函数名称)
# myDef函数无参数,无返回值
def set_fun(fun):
    def call_fun():
        print('这是闭包函数')
        print(f'参数fun的值为:{fun}')
        fun()

    return call_fun


# 被装饰函数myDef()
@set_fun
def myDef():
    print('---runing---')


if __name__ == '__main__':
    myDef()
# myDef函数有参数,无返回值
def set_fun(fun):
    def call_fun(num, *args, **kwargs):
        print('这是闭包函数')
        print(f'参数fun的值为:{fun}')
        print(f'参数num的值为:{num}')
        fun(num, *args, **kwargs)

    return call_fun


# 被装饰函数myDef()
@set_fun
def myDef(num, *args, **kwargs):
    print('---runing---')


if __name__ == '__main__':
    myDef(1)
# myDef函数有参数,有返回值
def set_func(fun):
    def call_func(num, *args, **kwargs):
        print('这是闭包函数')
        print(f'参数fun的值为:{fun}')
        print(f'参数num的值为:{num}')
        # 如果被装饰函数设有返回值,那么装饰器的内层函数也要设置相应的返回值
        # 返回值必须为被装饰函数fun()的调用过程
        return fun(num, *args, **kwargs)

    return call_func


@set_func
def myDef(num, *args, **kwargs):
    print('---------running---------')
    return num


if __name__ == '__main__':
    m = myDef(10)
    print('函数返回值为:', m)
# 一个函数使用两个或两个以上装饰器,无论函数是否有返回值,装饰器的内层函数必须设置返回值
def set_func1(fun):
    def call_func1(num, *args, **kwargs):
        print('这是第一个闭包函数')
        print(f'参数fun的值为:{fun}')
        print(f'参数num的值为:{num}')
        return fun(num, *args, **kwargs)

    return call_func1


def set_func2(fun):
    def call_func2(num, *args, **kwargs):
        print('这是第二个闭包函数')
        print(f'参数fun的值为:{fun}')
        print(f'参数num的值为:{num}')
        return fun(num, *args, **kwargs)

    return call_func2


@set_func1
@set_func2
def myDef(num, *args, **kwargs):
    print('---------running---------')
    return num


if __name__ == '__main__':
    m = myDef(10)
    print('函数返回值为:', m)

  • 总结
    1. 装饰器的外层函数的名称代表装饰器的名称,外层函数的参数fun代表被装饰函数的名称(函数myDef()),并且外层函数必须使用return设置返回值,返回值为内层函数的名称。
    2. 装饰器的内层函数主要调用被装饰函数,内层函数的参数等同于被装饰函数的参数。
    3. 如果被装饰函数设有返回值,内层函数也要设置相应的返回值,返回值必须为被装饰函数fun()(myDef())的调用过程。
    4. 多个装饰器装饰同一个函数,必须为装饰器的内层函数设置返回值;装饰器的执行顺序与被装饰函数的装饰器设置相关,从上往下执行,

3.3 带参数的函数装饰器

  • 如果要在装饰器中设置参数,整个装饰器就要定义3层函数
def set_para(parameter, *args, **kwargs):
    print('---第一层函数---')
    print(f'装饰器的参数parameter的值为:{parameter}')
    print(f'装饰器的参数args的值为:{args}')

    def set_func(fun):
        print('---第二层函数---')

        def call_func(num, *args, **kwargs):
            print('---第三层函数---')
            print(f'参数fun的值为:{fun}')
            print(f'参数num的值为:{num}')
            return fun(num, *args, **kwargs)

        return call_func

    return set_func


@set_para('Hello', 'Python')
def myDef(num, *args, **kwargs):
    print('---------running---------')
    return num


if __name__ == '__main__':
    m = myDef(10)
    print('函数返回值为:', m)
  • 如果装饰器需要设置函数参数,整个装饰器就需要设置3层函数,每层函数的功能说明如下:
  • 第一层函数负责接收装饰器的参数,装饰器的参数设置方式与普通函数的参数设置相同,并且它必须使用return设置返回值,返回值为第二层函数的名称。
  • 第二层函数接收被装饰函数,其函数参数fun代表被装饰函数的名称,它能使用第一层的函数参数,并且必须使用return设置返回值,返回值为第三层函数的名称。
  • 第三层函数负责调用被装饰函数,并且能使用第一层和第二层的函数参数,函数自身的参数等同于被装饰函数的参数,其返回值必须为被装饰函数的调用过程。

3.4 使用类定义装饰器

  • 使用类方式实现装饰器功能只需要定义初始化方法__ init __ ( ) 和内置方法 __ call __ ( )
# 类装饰器没有参数
class decorator:
    def __init__(self, fun):
        self.fun = fun

    def __call__(self, num, *args, **kwargs):
        res = self.fun(num, *args, **kwargs)
        return res


@decorator
def myDef(num, *args, **kwargs):
    print('---------Running---------')
    return num


if __name__ == '__main__':
    m = myDef(10)
    print('函数返回值为:', m)
  • 对比类装饰器与函数装饰器发现:
    • 初始化方法__ init __( )等同于无参数函数装饰器的最外层函数,都是负责接收被装饰函数
    • 内置方法__ call __( )等同于无参数函数装饰器的内层函数,主要实现被装饰函数的调用过程
# 类装饰器设置参数
class decorator:
    def __init__(self, para):
        self.para = para

    def __call__(self, func):
        print(f'装饰器的参数为:{self.para}')

        def wrapper(num, *args, **kwargs):
            res = func(num, *args, **kwargs)
            return res

        return wrapper


@decorator('hello')
def myDef(num, *args, **kwargs):
    print('---------Running---------')
    return num


if __name__ == '__main__':
    m = myDef(10)
    print('函数返回值为:', m)

  • 带参数的类装饰器定义过程如下:
    • 初始化方法__ init __( )负责接收装饰器的参数,等同于带参数函数装饰器的第一层函数。
    • 内置方法__ call __( )负责接收被装饰函数,其参数fun代表被装饰函数的名称,等同于带参数函数装饰器的第二层函数
    • 内置方法__ call __( )里面的函数方法wrapper( )负责调用被装饰函数,等同于带参数函数装饰器的第三层函数。

3.5 装饰器在类中的应用

  • 在函数或类的起那么添加【 @ 】符号和装饰器名称即可使用已定义的装饰器
# 在函数中使用装饰器
@decorator
def myDef():
	pass

# 在类中使用装饰器
@decorator
class myDef():
	pass
  • 除了在函数或类的前面使用装饰器外,还可以在类里面的某个方法或属性中使用装饰器

十、异常处理机制

1、异常的类型

  • 异常是指程序在运行过程中出现问题而导致无法执行,如程序的逻辑或算法错误、计算机资源不足或IO错误等

  • Python中的异常是由类定义的,所有的异常都是来自于BaseException类,不同类型的异常都继承自父类BaseException

  • Python中提供了异常处理机制,并定义了不同类型的异常信息:如AssertionError、AttributeError

2、捕捉异常

  • 在Python中,处理异常的语法由4个关键字组成,即try、except、else和finally
  • 具体语法格式如下:
try:
	# 程序运行的代码
except NameError as err:
    # 只捕捉NameError的错误类型
    print('错误信息1', err)
except Exception as err:
    print('错误信息2', err)
except:
    print('错误信息3')
else:
    print('如果没有异常就执行此处代码')
finally:
    print('不管是否有异常都会执行此处代码')

3、自定义异常

  • 自定义异常抛出除了监测错误之外,还可以用于代码的布局设计和程序的逻辑控制,通过抛出异常可以执行不同的代码块
  • 自定义异常抛出由关键字raise实现,关键字后面填写异常的类型及异常信息
if __name__ == '__main__':
    try:
        raise NameError('自定义异常抛出')
    except Exception as err:
        print('这是Exception错误,错误信息是:', err)
  • 自定义一个异常类只需要继承Exception类即可
# 自定义异常类型
class MyError(Exception):
    pass


if __name__ == '__main__':
    try:
        # 抛出自定义异常
        raise MyError('自定义异常抛出')
        # 捕捉自定义异常类
    except MyError as err:
        print('这是MyError错误,错误信息', err)

4、异常的追踪术

  • Python的标准库提供了traceback模块,它能准确定位代码的异常信息
import traceback


class A:
    pass


try:
    a = A()
    print(a.name)
    a.name = 10
    print(a.name)
except Exception as e:
    traceback.print_exc()

十一、模块与包

1、模块的导入与使用

  • 模块是由一组类、函数或变量等元素组成的,它存储在文件中,模块文件的扩展名可能是【.py】或【.pyc】
  • Python使用关键字import用于实现模块导入功能
# 导入方式1
import os,traceback,re

# 导入方式2
import os
import traceback
import re

2、包的导入与使用

  • 包是在同一组相同文件夹中放置了许多模块文件,这个文件就叫包,也称类库

  • 包的导入方式:

# 导入包
import html

# 导入包中的模块或子包
import html.parser

# 导入包中多层子包
import A.B.C.D

3、导入方式from…import…

  • 使用关键字from…import…导入模块或包
# 示例
from email import message
from email.mime import image

# 同一个包中导入多个模块文件
from email import meassage,parser,feedparser
from email.mime import image,base,multipart

# 导入模块文件中某个类、函数方法或变量
from email.message import EmailMessage

# 导入所有模块文件或者模块中所有的类、函数方法或变量
from email import *
from email.message import *

4、重命名模块与包

  • Python可以对导入的模块和包进行重新命名,使用关键字as即可实现
# 示例
from email import message as msg
from email.mime import image as img
  • 关键字as 还适用于单一导入方式import
import email.message as msg
import email.mime.image as img
  • 关键字as不支持导入方式是全部模块文件、类、函数方法或变量的重命名

5、自定义模块和包

  • 模块或包的自定义没有规定语法格式,只要定义的模块或包中含有类、函数方法或属性即可

6、重新加载模块与包

  • 一般情况下,我们导入模块或包后,当模块或包代码发生变化的时候,程序不会因为模块或包变化而变化
  • 在不中断程序的情况下,当导入模块或包的代码发生变化后,Python提供了importlib模块的reload( )方法重新加载模块或包

7、动态添加模块与包

  • 使用内置函数 __ import __ ( )可以动态加载模块或包
#  __ import __ ( )语法如下
__import__(name,globals,locals,fromlist,level)
参数:name是必填s

8、打包模块与包

  • Python的内置模块包setuptools可以将自定义的模块或包打包成 .whl
# 使用内置模块包setuptools的函数方法setup()创建打包文件
from setuptools import setup

setup(
	name='mypack'
  version='1.0'
  py_modules=['a','b','c']
  author='xxx'
  install_requires=[]
  packages=['mys']
)
  • 执行打包文件
# 必须安装wheel模块
pip install wheel

# 执行打包命令
python setup.py sdist bdist_wheel

9、安装第三方模块和包

  • Python提供了pip管理工具来管理第三方模块或包,它提供了对模块或包的查找、下载、安装、卸载等功能
# install指令语法
# 查看install指令的帮助信息
# pip install -help

# 示例
# 默认安装新版本的模块或包
# 如果安装的模块或包依赖其他模块或包,install指令就会将相关依赖一并安装
# pip install django
# 安装指定版本的模块或包
# pip install django==3.0.8
# 安装.whl文件
# install后面最好写上文件的绝对路径
# 如果PyCharm的Terminal或CMD窗口的当前路径下含有.whl文件,那么可以输入.whl文件的相对路径
# pip install C:\xxx.whl

# download指令语法
# 查看download指令的帮助信息
# pip download -help
# 示例
# 默认下载新版本的模块或包
# 如果下载的模块或包依赖其他模块或包,download指令就会将相关依赖一并下载
# pip download requests
# 下载指定版本的模块或包
# pip download requests==2.17.3

# uninstall指令语法
# 查看uninstall指令的帮助信息
# pip uninstall -help
# 示例
# 卸载已安装的模块或包
# pip uninstall django
# 卸载尚未安装的模块或包,程序提示模块或包尚未安装
# 提示:WARNING: Skipping abc as it is not installed
# pip uninstall abc
# list指令语法
# 查看list指令的帮助信息
# pip list -help
# 示例
# 查看当前已安装的模块或包
# pip list
  • pip管理工具除了安装,还能迁移Python开发环境
# pip管理工具提供了freeze指令,将当前环境安装的第三方模块或包的信息写入requirements.txt
# 在新环境中,只需要使用install执行requirements.txt文件,pip管理工具会根据文件记录执行相应的安装命令
# 打包安装文件信息
freeze > requirements.txt

# 执行安装命令
pip install -r requirements.txt
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值