Python学习笔记7

异常处理
包和模块

  • 包和模块的一般操作
  • 导入操作的本质
  • 模块检索的路径
  • 导入模块的场景
  • 第三方包和模块的安装

异常处理

  • 系统内部一开始已经内置了一些特定的错误场景,当我们触发了这个场景时,系统内部就会向外界抛出异常。如果我们没有处理,程序就会停止运行。

解决异常

  • 通过条件判断语句在程序内部进行容错检测,避免错误的发生。缺点: 如果要处理的错误太多,会有很多的和业务逻辑无关的代码。
  • 捕捉异常,然后再处理
try:
    # 可能出现异常的代码
    # 有异常就会抛出,不会再执行剩下的 try后面的代码
except xxxError as xxx:
    # 出现异常后,而且被捕捉到的代码
    # except可以写多个,用来捕捉多个不同的异常
else:
    # 异常未被捕捉到所执行的代码(可以省略)
finally:
    # 不管有没有异常都会执行的代码
  • 异常的合并解决
tyr:
    1 / 0
    print(val)
except (ZeroDivisionError, NameError) as e:
    print(e)
else
    print("fine like this")

# 执行结果:division by zero
# 如果不清楚异常的具体名字,可以写 Exception进行替代
  • 上下文管理器
# 在主要代码的执行前后分别添加一些操作
# 实现了 __enter__(), __exit__()两个函数的类产生的对象就是上下文管理器
class Test:
    def __enter__(self):
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        # exc_type: 异常类型
        # exc_val:  异常的值
        # exc_tb:   异常追踪信息
        # 函数有返回值,True表示异常已经处理,False表示异常还未处理
        print(exc_val)
        return True

with Test() as x:   # as 后面表示对象的__enter__()方法执行后的返回值
    1 / 0           # 产生的异常信息将对号入座传入__exit__()的函数参数中
    
# 执行结果: division by zero

# -----------------------------------------------------
# 通过 contexlib模块,通过生成器快速产生一个上下文管理器
import contexlib

# yield之前的代码相当于 __enter__()中的代码,但是返回结果要通过 yield来返回
# yield之后的代码相当于 __exit__()中的代码
@contexlib.contexmanager
def test():
    print(1)
    yield "x here"
    print(2)
    
with test() as x:
    print(3)
    print(x)
    
# 执行结果:
1
3
x here
2
  • with语句
with open("./xx.txt", "r") as f:
    f.readlines()
    
with open("a.jpg", "rb") as f1, open("b.jpg", "wb") as f2:
    content = f1.read()
    f2.write(content)
  • 手动抛出异常
# 通过 raise语句手动抛出异常
# 自己设计
def set_age(age):
    if age <= 0 or age > 150:
        raise ValueError("value error")
    print("age is %d" % age)

# 给别人调用
try:
    set_age(-18)
except ValueError as e:
    print(e)
  • 自定义异常
# 自定义的异常要直接或间接继承自:BaseException
class MyException(Exception):

包和模块

基本概念

  • 模块:将一组功能相关的代码写入一个单独的.py文件中,需要时进行导入,这个文件就是模块。
  • :有层次的文件目录结构,内部有多个模块多个子包,一般要有__init__.py这个文件(3.3+ 的版本不需要)。
  • :完成一定功能代码的集合,完成的功能一般更加广泛,可以是模块,也可以是包。
  • 框架:通过框架,可以快速实现解决某一个问题所需的代码骨架,后期进行填充即可。

包和模块的作用

  • 轮子,工具代码,供其他模块使用(模块化编程)
  • 划分了变量作用域,解决变量/函数重名的问题

包和模块分类

  • 内建的模块:builtin,会自动导入。
  • 第三方包/模块:由其他人员开发,需要下载安装才能使用。
  • 自定义包/模块:自己写的。

包和模块的一般操作

  • 创建模块
# 就是创建一个 .py文件
n1 = 1
n2 = 2
n3 = 3

def test():
    pass

__all__ = ["n1", "n2", "test"]  # 指定了可以导入到别的模块中的资源
  • 创建包:新建一个文件夹,为了兼容,添加一个__init__.py文件(当包被导入时,会运行这个文件)。
    • 在文件中设置__all__变量,可以限制能够通过from package import *所导出的模块。
  • 包和模块的导入方式
# -------------------------------
# 1.常规导入,导入了所有资源

import module

module.val      # 访问变量
module.func()   # 调用函数

# 模块在其他的包中
import p.module
p.module.val

# 一次导入多个模块
import p.module, module, module_2

# 给模块起别名
import p.module as m
m.val
m.func()

# -------------------------------
# 2.from语句导入,只导入部分资源

# 从包中导入模块
from p import module
module.val

from p import module1, module2
from p import module1 as m1, module2 as m2

from p.sub_p import m   # 正确写法
from p import sub_p.m   # 错误写法

# 从模块中导入资源
from module import val, func
print(val)      # 直接使用
func()

from p.mudule import val    # True
from p import module.val    # False

from p import *     # 导入了 p包下的所有模块,受到 __init__.py文件中__all__变量的约束
from module import *    # 导入了 module下的所有资源,受到模块中 __all__变量的约束

# 使用 * 进行导入,容易产生同名冲突

导入操作的本质

  • 第一次导入
    • 被导入的模块会在自己的命名空间中执行所有的代码。
    • 代码执行完成后,会产生一个模块对象,模块中的所有属性都绑定到这个对象上,对象的名称就是模块名。
    • 目标模块在import位置建立引用,就可以根据模块对象的名称来访问资源了。
  • 第二次导入
    • 直接建立到对象的引用,也就是第一次导入的第三步。
  • 两种导入方式都会执行模块的所有代码,所以不存在第二种方式更省内存的说法,只是拿不同的部分来使用。

模块检索路径

  • 检索模块按照一定的顺序进行,优先在具有较高优先级的地方查找。
  • 先在内置模块中查找,若自己定义了一个和内置模块重名的模块,进行导入时,会导入内置的那个模块。
  • 然后在sys.path(是一个路径列表)中查找
    • 当前目录
    • 环境变量PYTHONPATH
    • 特定路径下的.pth文件所指定的路径
    • python安装目录下的lib
  • 追加路径的方式 (在sys.path增加自定义的路径)
# 直接修改 sys.path
import sys

sys.path.append("xx/xx/xx")     # 添加自定义的一个路径,单次执行有效

import xxx      # xxx是位于自定义路径下的一个模块

# 直接修改 PYTHONPATH, 因为 sys.path包括了 PYTHONPATH
# 在 shell中有效,在 IDE中又要另外添加
# 作用持久

导入模块的场景

  • 局部导入
# 在需要使用的范围内进行导入,其他范围无法使用,多用于函数
def cal(r):
    
    import math
    return math.pi * r * r

erea = cal(2)
  • 覆盖导入
    • 自定义的模块名称和非内置的标准模块重名,根据优先级,前者会覆盖后者
    • 自定义的模块和内置模块重名,后者覆盖前者
  • 循环导入
    • A模块导入了 B模块,B模块又导入了 A模块
    • 会造成一些问题
  • 可选导入
# 对于两个功能相似的模块,想优先导入其中一个,若不存在,再导入另外一个
try:
    import module_1 as m
except ModuleNotFoundError:
    import module_2 as m
    
m.func()
  • 加载.py文件的两种方式
    • 脚本形式直接执行
      当一个含有导入模块操作的个文件被执行后,会将自身所在的路径添加到sys.path,后面的所有导入(在当前文件的其他导入 + 所导入模块中的其他导入)都会参照这个sys.path。同时,该文件有一个属性:__name__ = '__main__'
    • 作为模块被其他文件导入
      此时其__name__属性是由该模块的加载路径所决定的。这个路径作为相对导入时的路径参照。
  • 绝对导入和相对导入
# 绝对导入
# 参照sys.path路径进行模块检索的导入方式

import module
from module import func

# 相对导入
# 用 . 和 .. 来代替绝对路径进行模块的检索

from . import module    # 参考的路径是该模块被绝对导入时加载的路径

第三方包和模块的安装

包管理项目
  • distutils
    标准库的一部分,能处理简单的包安装,通过setup.py进行安装
  • setuptools
    现在的包安装标准,使用pip安装脚本,使用whl格式
三方包和模块的发布形式
  • 源代码
    一个压缩包,解压后里面有setup.py文件,运行即可完成安装
  • .egg
    setuptools引入的一种格式,压缩包,通过安装脚本easy_install进行安装
  • .whl
    为了替代.egg,压缩包,使用pip进行安装
安装方式
  • 本地安装
    • 单文件模块
      直接拷贝到sys.path中包含的路径即可,一般放在Lib/site-packages/
    • 带有setup.py文件
      直接使用命令进行安装2.xpython2 setup.py install3.xpython3 setup.py install,注意执行命令时的所在目录即可。
    • .egg文件的安装,使用setuptools的自带安装脚本easy_install进行安装,前提要先安装好easy_install安装命令easy_install xxx.egg
    • .whl文件的安装,推荐使用pip安装。首先要安装pip,一般会自动装上(若没有装,使用easy_install 进行远程安装)。安装命令pip install xxx.whl
  • 远程安装
    • 自动地从远程下载地址进行检索、下载、安装
    • easy_install xxx
    • pip install xxx
    • 默认安装在Lib/site_packages/
    • 默认是从官网上下载,建议更换安装源。
  • 安装源(镜像地址)
其他问题
easy_install
  • python版本的切换安装
    • easy_install-2.7 xxx
    • easy_install-3.6 xxx
  • 安装指定版本的包
    • 默认是安装最新的版本
    • easy_install "requests >= 2.14.1" 安装大于或等于2.14.1版本的最新包
    • easy_install "requests > 1.0, < 2.0" 安装大于1.0且小于2.0的包
    • easy_install "requests == 2.14.1" 安装当前版本的包,若已经安装,则切换到这个版本
  • 升级第三方包
    • easy_install --upgrade requests
  • 卸载第三方包
    • 手动卸载:1.删除在easy_install.pth中的包记录,2.删除对应的包文件。
    • 命令卸载:easy_install -m requests,并不是真正地卸载了库,相当于执行手动卸载的第一步
    • 对于命令卸载,以后还可以继续使用这个包,只不过不能直接使用
      import pkg_resources
      pkg_resources.require("requires==2.18.4")   # 指明你需要的版本
      import requests
      
  • 修改安装源
    • setuptools/command/easy_install.py在里面修改安装源即可
pip
  • 修改安装源(Windows)
    • 在用户名下创建pip目录,在目录中创建pip.ini文件。C:\Users\xx\pip\pip.ini
    • 编辑文件内容如下:
      [global]
      index-url = http://pypi.douban.com/simple/
      
      trusted-host = pypi.douban.com
      
  • 修改安装源(Linux)
    • 在用户名下创建.pip目录,目录下创建pip.conf文件。/home/xxx/.pip/pip.conf
    • 文件中的内容和上面相同
  • python版本安装
    • python -m pip install requests
    • python3 -m pip install requests
  • 查看包:pip list
  • 安装指定版本包:pip install "requests >= 1.14.1"
  • 升级包:pip install -- upgrade requests
  • 安装多个版本的库,会以最后一次安装的为准,覆盖安装。若再次执行pip install requests,会给出包已经存在的提示。
  • 卸载包:pip uninstall requests,会删除包文件。
  • 生成冻结需求文本:将当前安装的第三方包记录,储存到指定的文件中,以后,就可以根据这个需求去安装三方包。
    pip freeze > ./requirements.txt
    pip install -r requirements.txt
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容