模块异常谈python

作者:白宁超

2016年10月10日12:08:31

摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下。官方给出的pythondoc入门资料包含了基本要点。本文是对文档常用核心要点进行梳理,简单冗余知识不再介绍,作者假使你用c/java/c#/c++任一种语言基础。本系列文章属于入门内容,老鸟可以略看也可以略过,新鸟可以从篇一<快速上手学python>先接触下python怎样安装与运行,以及pycharm编辑器的使用和配置;篇二<数据结构看python>介绍python语言中控制语句、列表、字典、元组、循环等基本操作;篇三<函数修行知python>细解python语言函数的范畴与内容;篇四<模块异常谈python>采用登录的案例详解模块来龙去脉;篇五<‘类’过依然继续前行,直至ending再出发>介绍类的基本操作,扩展虚拟环境、标准类库和下个系列预告。(本文原创,转载注明出处:模块异常谈知python)

目录:


【Python五篇慢慢弹(1)】快速上手学python
【Python五篇慢慢弹(2)】数据结构看python
【Python五篇慢慢弹(3)】函数修行知python
【Python五篇慢慢弹(4)】模块异常谈python
【Python五篇慢慢弹(5)】‘类’过依然继续前行,直至ending再出发

1 模块


【小记】本文中所有代码经过测试均可正常运行,python有个问题就是复制后会破坏原有格式。所以读者复制运行时报如下错误:SyntaxError: expected an indented block,是因为空格问题,可以预留4个空格,或者采用tab键空格

python脚本:如果你想要编写一些更大的程序,并把程序写入一个.py的文件作为执行文件。

模块定义:在脚本或者解释器的一个交互式实例中使用。这样的文件被称为模块;模块中的定义可以导入到另一个模块或主模块中。模块是包括 Python 定义和声明的文件。文件名就是模块名加上.py 后缀。模块的模块名可以由全局变量 __name__(类似主函数)得到。

登陆权限限制实例解析模块
实例分析

通过前面文章介绍python基本语法和例子,大家对python已经不陌生了。现在咱们做一个登录的案例,要求如下:

①创建脚本:在pycharm(快速上手学python 有介绍)或者IDLE(python 3.5)中创建一个LoginDome.py

②登录函数:定义一个login()函数,当用户输入用户名密码同时匹配时,登录成功,反之登录失败。3次机会不成功锁定账号。

③信息收集:每次登录的用户名和密码放在一个列表里面。

④模块测试:完成以上案例后,使用pycharm自动对类创建测试单元

⑤模块调用:新建一个moduleTest.py去调用之前的login()函数

实例演示:LoginDome.py 的文件,录入如下内容

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__title__ = ''
__author__ = 'cuitbnc'
__mtime__ = '2016/10/4'
# 欢迎进入我的主页:http://www.cnblogs.com/baiboy/.
""" '''默认函数值:最常用的一种形式是为一个或多个参数指定默认值
username:必选参数,用户名
password:必选参数,密码
limits:可选参数,登陆权限限制
complaint:可选参数,登陆错误,剩余次数提示
urs=[] :字典参数
'''
def login(username,password, limits=3, complaint='you have login times:【',urs=[]):
countlimits = limits; #统计自定义限制次数
while True:
usrname= input(username)
usrpwd=input(password)
urs.append("you input data:["+usrname+"-"+usrpwd+"]") # 记录用户每次登录的信息
print(urs)
if usrname in ('admin', 'ad', 'bnc') and usrpwd in ('pass', 'pwd', 'password', 'bnc'):
print('Congratulations,Welcome 【'+usrname+'】to the login page.')
return
else:
print('Sorry,【'+usrname+'】:you username or password error.')
limits = limits - 1
if limits == 0:
print('More '+str(countlimits)+' times,Your account is locked!')
return
print(complaint+str(limits)+"】times")

1、只给出必要的参数运行结果:

# 只给出必要的参数:
login('UserName:\t','PassWord:\t')

 

解析:

默认函数值:最常用的一种形式是为一个或多个参数指定默认值,当只输入必选参数时候默认登陆权限是3次,登陆错误的提示也是默认值。具体效果如上图

2、给出必要的参数和权限次数限制运行结果:

# 给出一个可选的参数
login('UserName:\t','PassWord:\t',2)

 

解析: 

可选参数咱们手动设置2次,运行效果如图。

3、给出必选参数,限制权限2次,且自定义给出错误提示运行效果:

# 或者给出所有的参数
login('UserName:\t','PassWord:\t', 2, 'Remember you enter the correct user name and password,you have login times:')

解析:

自定义的错误提示如图所示。

自动创建模块的单元测试:

1)选中login函数名,按下Ctrl+Shift+T,或者Navigate → Test自动生成测试类

2)自动生成效果如下图:pass没有具体含义,占位符理解。

3)运行测试类结果:

模块调用:

1)新建一个Python文件命名moduleTest.py,录下以下代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
__title__ = ''
__author__ = 'cuitbnc'
__mtime__ = '2016/10/9'
# 欢迎进入我的主页:http://www.cnblogs.com/baiboy/.
"""
import LoginDome
LoginDome.login('UserName:\t\n','PassWord:\t\n')

运行结果:

注意:运行调用模块名.方法名([形参])

2、深入模块


模块(py文件名)全局变量的使用:modname.itemname
模块导入的几种方式
①import ModuleName
②from ModuleName import MethodName1, MethodName1
③from ModuleName import * (不推荐,这样导入后代码没有那么清晰,不过交互式时候可以用)
注意:出于性能考虑,每个模块解释器会话中只导入一遍。因此,如果你修改了你的模块,需要重启解释器;或者可以用 imp.reload() 重新加载,例如 import imp; imp.reload(modulename)。

模块的搜索路径
导入一个叫LoginDome的模块时,解释器先在当前目录中搜索名为LoginDome.py 的文件。如果没有找到的话,接着会到 sys.path 变量中给出的目录列表中查找。
sys.path 变量的初始值来自如下:
输入脚本的目录(当前目录)。
环境变量 PYTHONPATH 表示的目录列表中搜索
实际上,解释器由 sys.path 变量指定的路径目录搜索模块,该变量初始化时默认包含了输入脚本(或者当前目录), PYTHONPATH 和安装目录。

编译的” Python 文件
为了加快加载模块的速度,Python 会在 __pycache__ 目录下以 module.version.pyc 名字缓存每个模块编译后的版本,这里的版本编制了编译后文件的格式。它通常会包含 Python 的版本号。
例如,在 CPython 3.3 版中,spam.py 编译后的版本将缓存为 __pycache__/spam.cpython-33.pyc。这种命名约定允许由不同发布和不同版本的 Python 编译的模块同时存在。
Python 会检查源文件与编译版的修改日期以确定它是否过期并需要重新编译。这是完全自动化的过程。同时,编译后的模块是跨平台的,所以同一个库可以在不同架构的系统之间共享。
Python 不检查在两个不同环境中的缓存。首先,它会永远重新编译而且不会存储直接从命令行加载的模块。其次,如果没有源模块它不会检查缓存。若要支持没有源文件(只有编译版)的发布,
编译后的模块必须在源目录下,并且必须没有源文件的模块。
部分高级技巧
1 为了减少一个编译模块的大小,你可以在 Python 命令行中使用 -O 或者 -OO。-O 参数删除了断言语句,-OO 参数删除了断言语句和 __doc__ 字符串。因为某些程序依赖于这些变量的可用性,你应该只在确定无误的场合使用这一选项。“优化的” 模块有一个 .pyo 后缀而不是 .pyc 后缀。未来的版本可能会改变优化的效果。
2 来自 .pyc 文件或 .pyo 文件中的程序不会比来自 .py 文件的运行更快;.pyc 或 .pyo 文件只是在它们加载的时候更快一些。
3 compileall 模块可以为指定目录中的所有模块创建 .pyc 文件(或者使用 -O 参数创建 .pyo 文件)。

标准模块
Python 带有一个标准模块库,并发布有独立的文档,名为 Python 库参考手册。
例如,winreg 模块只提供在 Windows 系统上才有。有一个具体的模块值得注意: sys ,这个模块内置于所有的 Python 解释器。变量 sys.path和 sys.version

>>> import sys
>>> sys.path
['', 'E:\\Python\\Lib\\idlelib', 'E:\\Python\\python35.zip', 'E:\\Python\\DLLs', 'E:\\Python\\lib', 'E:\\Python', 'E:\\Python\\lib\\site-packages']
>>> sys.version
'3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)]'

变量 sys.path 是解释器模块搜索路径的字符串列表。它由环境变量 PYTHONPATH 初始化,如果没有设定 PYTHONPATH ,就由内置的默认值初始化。你可以用标准的字符串操作修改它:

3、dir() 函数


内置函数 dir() 用于按模块名搜索模块定义,它返回一个字符串类型的存储列表

dir()内置函数实例:dir() 不会列出内置函数和变量名。如果你想列出这些内容,它们在标准模块 builtins 中定义
import sys,LoginDome,builtins
print("LoginDome 内置函数:"+str(dir(LoginDome)))
print("Sys 内置函数:"+str(dir(sys)))
print("builtins 内置函数变量名:"+str(dir(sys)))

LoginDome 内置函数

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'login']

Sys 内置函数:

['__displayhook__', '__doc__', '__excepthook__', '__interactivehook__', '__loader__', '__name__', '__package__', '__spec__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe', '_home', '_mercurial', '_xoptions', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'get_coroutine_wrapper', 'getallocatedblocks', 'getcheckinterval', 'getdefaultencoding', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 'getwindowsversion', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'is_finalizing', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'set_coroutine_wrapper', 'setcheckinterval', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'version', 'version_info', 'warnoptions', 'winver']

builtins 内置函数变量名:

['__displayhook__', '__doc__', '__excepthook__', '__interactivehook__', '__loader__', '__name__', '__package__', '__spec__', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe', '_home', '_mercurial', '_xoptions', 'api_version', 'argv', 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'get_coroutine_wrapper', 'getallocatedblocks', 'getcheckinterval', 'getdefaultencoding', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettrace', 'getwindowsversion', 'hash_info', 'hexversion', 'implementation', 'int_info', 'intern', 'is_finalizing', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'set_coroutine_wrapper', 'setcheckinterval', 'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout', 'thread_info', 'version', 'version_info', 'warnoptions', 'winver']

4、包


包(模块集):用“圆点模块名”的结构化模块命名空间。例如, A.B 的模块表示了名为 A 的包中名为 B 的子模块。不同的模块架构可以避免冲突,

模块集统一处理声音文件和声音数据。存在几种不同的声音格式(例如:.wav, .aiff,.au )。可能你还想要对声音数据做很多不同的操作(例如混音,添加回声,应用平衡 功能,创建一个人造效果),所以你要加入一个无限流模块来执行这些操作。你的包可能会是这个样子:

sound/                          Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py

当导入这个包时,Python 通过 sys.path 搜索路径查找包含这个包的子目录。为了让 Python 将目录当做内容包,目录中必须包含 __init__.py 文件。当然它也可以执行包的初始化代码,或者定义稍后介绍的 __all__ 变量。

导入包的几种方式:
①导入包里的特定模块:
例如:import sound.effects.echo (导入 sound.effects.echo 子模块)
调用:sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
②导入包可以选择方式
例如:from sound.effects import echo
调用: echo.echofilter(input, output, delay=0.7, atten=4)
③直接导入函数或变量
例如:from sound.effects.echo import echofilter (直接调用它的 echofilter() 函数)
调用:echofilter(input, output, delay=0.7, atten=4)

导包原理:使用 from package import item 方式导入包时,这个子项(item)既可以是包中的一个子模块(或一个子包),也可以是包中定义的其它命名,像函数、类或变量。import 语句首先核对是否包中有这个子项,如果没有,它假定这是一个模块,并尝试加载它。如果没有找到它,会引发一个 ImportError 异常。相反,使用类似 import item.subitem.subsubitem 这样的语法时,这些子项必须是包,最后的子项可以是包或模块,但不能是前面子项中定义的类、函数或变量。

从 * 导入包
import 语句执行from package import * 时,如果包中的 __init__.py 代码定义了一个名为 __all__ 的列表,就会按照列表中模块名进行导入。新版本的包发布可以任意更新__all__列表。如果包作者不想 import * 的时候导入他们的包中所有模块,那么也可能会决定不支持它( import * )。
例如, sound/effects/__init__.py 这个文件可能包括如下代码:__all__ = ["echo", "surround", "reverse"]
这意味着 from Sound.Effects import * 语句会从 sound 包中导入以上三个已命名的子模块。

包内引用
例如: sound.filters.vocoder 包需要使用 sound.effects 包中的 echo 模块,它可以 from Sound.Effects import echo。包内引用可以.代表上级目录
from . import echo 等于 (from Sound.Effects import echo)
from .. import formats 等于 (from Sound import formats)
from ..filters import equalizer 等于(from Sound.filters import equalizer)
需要注意的是显式或隐式相对位置导入都基于当前模块的命名。因为主模块的名字总是 "__main__",Python 应用程序的主模块应该总是用绝对导入。

5、错误和异常


errors:语法错误
exceptions:异常
例子:它会一直要求用户输入,直到输入一个合法的整数为止,但允许用户中断这个程序。注意:用户产生的中断会引发一个 KeyboardInterrupt 异常。

>>> while True:
try:
x = int(input("Please enter a number: "))
break
except ValueError:
print('oh,That was no valid number. Try again...') Please enter a number: rttr
oh,That was no valid number. Try again...
Please enter a number:

try 语句按如下工作方式

  1. 执行 try 子句 (在 try 和 except 关键字之间的部分)。
  2. 如果没有异常发生, except 子句 在 try 语句执行完毕后就被忽略了。
  3. 如果在 try 子句执行过程中发生了异常,那么该子句其余的部分就会被忽略。如果异常匹配于 except 关键字后面指定的异常类型,就执行对应的except子句。然后继续执行 try 语句之后的代码。
  4. 如果发生了一个异常,在 except 子句中没有与之匹配的分支,它就会传递到上一级 try 语句中。如果最终仍找不到对应的处理语句,它就成为一个 未处理异常,终止程序运行,显示提示信息。

一个 try 语句可能包含多个 except 子句,分别指定处理不同的异常。例如:(RuntimeError, TypeError, NameError)最后一个 except 子句可以省略异常名称:

import sys
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except OSError as err:
print("OS error: {0}".format(err))
except ValueError:
print("Could not convert data to an integer.")
except:
print("Unexpected error:", sys.exc_info()[0])
raise

try ... except 语句可以带有一个 else子句,该子句只能出现在所有 except 子句之后。当 try 语句没有抛出异常时,需要执行一些代码,可以使用这个子句。例如:

for arg in sys.argv[1:]:
try:
f = open(arg, 'r')
except IOError:
print('cannot open', arg)
else:
print(arg, 'has', len(f.readlines()), 'lines')
f.close()

异常处理器不仅仅处理那些在 try 子句中立刻发生的异常,也会处理那些 try 子句中调用的函数内部发生的异常。例如:

>>> def this_fails():
... x = 1/0
>>> try:
... this_fails()
... except ZeroDivisionError as err:
... print('Handling run-time error:', err)
Handling run-time error: int division or modulo by zero

抛出异常:raise 语句允许程序员强制抛出一个指定的异常。例如:

>>> try:
raise NameError('There name error')
except NameError:
print('An exception flew by!')
raise An exception flew by!
Traceback (most recent call last):
File "<pyshell#196>", line 2, in <module>
raise NameError('There name error')
NameError: There name error

定义清理行为

程序:

运行结果:

预定义清理行为
读取文件:(文件操作将在下篇介绍

读取文件:
for line in open("myfile.txt"):
print(line)
如上文件读取没有关闭,则可以采用之前文章介绍的预处理with解决:
with open("myfile.txt") as f:
for line in f:
print(line)

6、参考文献和推荐资料


  1. Python 官方网站 :包含代码、文档和 Web 上与 Python 有关的页面链接该网站镜像于全世界的几处其它问题,类似欧洲、日本和澳大利亚。镜像可能会比主站快,这取决于你的地理位置
  2. 快速访问 Python 的文档
  3. Python 包索引 :索引了可供下载的,用户创建的 Python 模块。如果你发布了代码,可以注册到这里,这样别人可以找到它
  4. The Scientific Python : 项目包括数组快速计算和处理模块,和大量线性代数、傅里叶变换、非线性solvers、随机数分布,统计分析以及类似的包
  5. 官方python学习文档
  6. 简明Python教程
  7. 廖雪峰:python教程
  8. Python官网文档
  9. 【51cto学院,入门课程】Python零基础入门学习视频教程
  10. 【个人博客:案例】GitHub数据提取与分析
  11. 【csdn】python知识库
  12. 【社区】python中文学习大本营
  13. 【个人博客】老王python
												

【Python五篇慢慢弹(4)】模块异常谈python的更多相关文章

  1. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  2. 【Python五篇慢慢弹】数据结构看python

    数据结构看python 作者:白宁超 2016年10月9日14:04:47 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...

  3. 【Python五篇慢慢弹(3)】函数修行知python

    函数修行知python 作者:白宁超 2016年10月9日21:51:52 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...

  4. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸

    类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...

  5. python五十四课——datetime模块

    3.datetime模块:理解:datetime可以认为是time模块的补充/扩展datetime模块中有一些常用类:datetime类:记录了日期和时间数据信息date类:记录了日期数据信息time ...

  6. Python基础篇 -- 小数据池和再谈编码

    小数据池 1. id() 通过id()可以查看到一个变量表示的值在内存中的地址 s = "Agoni" print(id(s)) # 2410961093272 2. is 和 = ...

  7. python线程池(threadpool)模块使用笔记 .python 线程池使用推荐

    一.安装与简介 pip install threadpool pool = ThreadPool(poolsize) requests = makeRequests(some_callable, li ...

  8. 文成小盆友python-num7 -常用模块补充 ,python 牛逼的面相对象

    本篇内容: 常用模块的补充 python面相对象 一.常用模块补充 1.configparser模块 configparser 用于处理特定格式的文件,起内部是调用open()来实现的,他的使用场景是 ...

  9. 浅谈 Python 程序和 C 程序的整合

    源地址:http://www.ibm.com/developerworks/cn/linux/l-cn-pythonandc/ 概览 Python 是一种用于快速开发软件的编程语言,它的语法比较简单, ...

随机推荐

  1. 2015 西雅图微软总部MVP峰会记录

    2015 西雅图微软总部MVP峰会记录 今年决定参加微软MVP全球峰会,在出发之前本人就已经写这篇博客,希望将本次会议原汁原味奉献给大家 因为这次是本人第一次写会议记录,写得不好的地方希望各位园友见谅 ...

  2. CoreCRM 开发实录——Travis-CI 实现 .NET Core 程度在 macOS 上的构建和测试 [无水干货]

    上一篇文章我提到:为了使用"国货",我把 Linux 上的构建和测试委托给了 DaoCloud,而 Travis-CI 不能放着不用啊.还好,这货支持 macOS 系统.所以就把 ...

  3. 基于Oracle安装Zabbix

    软件版本 Oracle Enterprise Linux 7.1 64bit Oracle Enterprise Edition 12.1.0.2 64bit Zabbix 3.2.1 准备工作 上传 ...

  4. CRL快速开发框架系列教程五(使用缓存)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  5. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  6. C# 生成验证码图片时消除锯齿

    引言 基于生成图片实现了一个手机号转图片的需求. 内容也很简单,直接用手机号生成一个png图片.就是为了背景透明以便其他地方调用. 有无锯齿主要依靠一句代码:g.TextRenderingHint= ...

  7. .NET同步与异步之相关背景知识(六)

    在之前的五篇随笔中,已经介绍了.NET 类库中实现并行的常见方式及其基本用法,当然.这些基本用法远远不能覆盖所有,也只能作为一个引子出现在这里.以下是前五篇随笔的目录: .NET 同步与异步之封装成T ...

  8. Android开发学习—— Broadcast广播接收者

    现实中:电台要发布消息,通过广播把消息广播出去,使用收音机,就可以收听广播,得知这条消息.Android中:系统在运行过程中,会产生许多事件,那么某些事件产生时,比如:电量改变.收发短信.拨打电话.屏 ...

  9. Struts2日期类型转换

    针对日期类java.util.Date进行类型转换,要求客户端使用"yyyy-MM-dd","yyyy/MM/dd"中的任意一种输入,并以"yyyy- ...

  10. Storm

    2016-11-14  22:05:29 有哪些典型的Storm应用案例? 数据处理流:Storm可以用来处理源源不断流进来的消息,处理之后将结果写入到某个存储中去.不像其它的流处理系统,Storm不 ...