异常和模块学习

with:它是一种上下文管理协议
with通过__enter__方法初始化,然后在__exit__中做善后以及处理异常。所以使用with处理的对象必须有__enter__()和__exit__()这两个方法。其中__enter__()方法在语句体(with语句包裹起来的代码块)执行之前进入运行__exit__()方法在语句体执行完毕退出后运行。

with 语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等.

With语句的基本语法格式如下:
with expression [as target]:
with_body

参数说明:
expression:是一个需要执行的表达式;
target:是一个变量或者元组,存储的是expression表达式执行返回的结果,可选参数。

with语句的工作原理:
紧跟with后面的语句会被求值,返回对象的__enter__()方法被调用,这个方法的返回值将被赋值给as关键字后面的变量,当with后面的代码块全部被执行完之后,将调用前面返回对象的__exit__()方法。

自定义with异常

class opened(object):
def init(self, filename):
self.handle = open(filename)
print (‘Resource: %s’% filename)
def enter(self): #执行之前进入运行
print (’[Enter %s]: Allocate resource.’ % self.handle)
return self.handle # 可以返回不同的对象
def exit(self, exc_type, exc_value, exc_trackback): #执行完毕退出后运行
print (’[Exit %s]: Free resource.’ % self.handle)
if exc_trackback is None:
print (’[Exit %s]: Exited without exception.,’ % self.handle)
self.handle.close()
else:
print (“error occur!”) #句柄泄漏
#return True
return False #会抛出异常,中断程序的执行
with opened(r’e:\xx.txt’) as fp:
for line in fp.readlines():
print(line)
raise TypeError

print (“Done”)

断言:
assert断言是声明其布尔值必须为真的判断,如果发生异常就说明表达式为假。如果断言成功不采取任何措施(类似语句),否则触发AssertionError(断言错误)的异常

#coding=utf-8
def add(x,y,*d):
result = x + y
for i in d :
result += i
return result

print("add(1,2,[1,2,3])=",add(1,2,[1,2,3]))

if name == ‘main’ :
assert 9 == add(1,2,*[1,2,3]) #断言成功,所以不采取任何措施

执行结果:
add(1,2,*[1,2,3])= 9

if name == ‘main’ :
assert 10 == add(1,2,*[1,2,3]) #断言失败,触发AssertionError(断言错误)的异常

执行结果:
add(1,2,[1,2,3])= 9
Traceback (most recent call last):
File “C:/Users/admin/PycharmProjects/untitled1/test.py”, line 11, in
assert 10 == add(1,2,
[1,2,3])
AssertionError

模块的定义:
➢ 模块让你能够更有逻辑地组织你的Python代码段。
➢ 把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
➢ 模块也是Python对象,具有随机的名字属性用来绑定或引用。
➢ 简单地说,模块就是一个保存了Python代码的文件。模块能定义函数、类和变量。模块里也能包含可执行的代码。
➢ 模块是Python中最高级别的程序组织单元,它将程序代码和数据封装起来以便重用,而模块就对应Python中的程序文件(.py文件),一旦在一个.py文件中导入了其他模块之后就可以在这个文件中使用导入模块中的变量、函数或类等。模块可以由两个语句和一个内置的函数reload()导入。
➢ import:导入一个整体的模块
➢ from:从一个模块中获取一些特定的内容
➢ reload:在不中止Python程序的情况下,重新导入模块文件内容的方法。

命名空间和作用域:
一个Python表达式可以访问局部命名空间和全局命名空间里的变量。如果一个局部变量和一个全局变量重名,则局部变量会覆盖全局变量。
每个函数都有自己的命名空间。类的方法的作用域规则和通常函数的一样。Python会智能地猜测一个变量是局部的还是全局的,它假设任何在函数内赋值的变量都是局部的。因此,如果要给全局变量在一个函数里赋值,必须使用global关键字,声明该变量为全局变量,否则就会认为是局部变量而重新开辟一段空间。
Global VarName的表达式会告诉Python,VarName是一个全局变量,这样Python就不会再局部命名空间里去寻找这个变量了。函数外的list变量在函数内使用无需声明为global。

举例:

Money=2000
def AddMoney():

global Money

Money=Money+1

print (Money)
AddMoney()
print (Money)

执行结果:
2000
Traceback (most recent call last):
File “C:/Users/admin/PycharmProjects/untitled1/test.py”, line 8, in
AddMoney()
File “C:/Users/admin/PycharmProjects/untitled1/test.py”, line 6, in AddMoney
Money=Money+1
UnboundLocalError: local variable ‘Money’ referenced before assignment

修改后:
Money=2000
def AddMoney():
global Money
Money=Money+1
print (Money) #在未调用函数前,Money的值不会发生变化
AddMoney()
print (Money) #在使用函数后,Money的值才会发生变化

执行结果:
2000
2001

导入模块方法:
import module1 #导入一个模块
import module1, module2,… moduleN #导入多个模块
from modname import module1 #从模块中导入一个指定的部分到当前命名空间,这个声明不会把整个模块导入到当前的命名空间,它只会把module1模块中的modname函数导入到执行这个声明的模块的全局符号表中
from modname import * #该语句表示将一个模块的所有内容全都导入到当前的命名空间。这是一种简单的导入一个模块中的所有项目,但是这种方法不推荐过多的使用。

reload() #需要从imp中引入,表示重新导入已导入过的模块。
语法如下:
from imp import reload
reload(module_name)
比如:reload(math)

说明:
使用reload()的时候,有一些标准。
首先:模块必须是全部被导入,也就是必须是使用import导入的模块。
其次:模块必须被导入成功。
然后:reload()参数必须是模块自身,而不是包含模块名的字符串。也就是说,必须是reload(math),而不是reload(‘math’)。
最后:reload()再次导入的模块,会再次被执行,跟import不同。

import和from…import…的区别

  1. import导入的是一整个模块,而from…import…导入的却是模块中某些特定的内容。
  2. import导入的内容是存放在模块命名空间中的,而from…import…却是存放在当前命名空间中的。
  3. 使用import导入的模块,访问其中的属性与方法时,需要使用模块名.方法名(或属性名等)。
  4. 使用from…import…导入的模块,由于是导入到当前的命名空间中的,所以只需要直接使用属性名或方法名即可。
  5. 当导入的多个模块中含有同名方法或属性时,如果使用import导入,后导入的同名方法或属性不会覆盖先导入的其他模块中的同名的方法或属性;如果使用from…import…导入的,后导入的同名属性或方法会覆盖最先导入的其他模块中的同名方法或属性。

说明:

  1. 导入模块的语句最规范的做法是放在脚本的顶端,当然也可以在需要的地方直接导入需要的模块。
  2. 导入一个模块时,模块中顶格写的代码(也就是没有缩进的代码)都会被执行一遍。
  3. 一个模块只会被导入一次,而且是最早导入的那次,不管你执行了多少次import语句,这样是为了防止导入的模块被一遍又一遍的执行。
  4. reload()导入后,模块中顶格代码仍会被执行一次。

定位模块:
当导入一个模块时,Python解析器会去搜索该模块存在的位置,其搜索顺序为:
➢ 当前目录
➢ 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录(配置的环境变量),用sys.path.append来进行添加。
➢ 如果都找不到,python会查安装路径lib下的site-packages。Unix下,默认路径一般是/usr/local/python/。模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH由安装过程决定的默认目录。

PYTHONPATH(环境变量)设置方式:
在Windows系统,典型的PYTHONPATH如下:
set PYTHONPATH=c:\python20\lib;

在UNIX系统,典型的PYTHONPATH如下:
set PYTHONPATH=/usr/local/lib/python

globals()和locals()函数:
根据调用地方的不同,globals()和locals()函数可被用来返回全局和局部命名空间里的名字。
如果在函数内部调用locals(),返回的是所有能在该函数里访问的命名。
如果在函数内部调用globals(),返回的是所有在该函数里能访问的全局名字。
两个函数的返回类型都是字典。所以名字们能用keys()函数摘取。

#encoding=utf-8
print (“main’s globals1:”, globals().keys())
print (“main’s locals1:”, locals().keys())
print("**************")
def foo():
print (“calling foo()…”)
aStr = “bar”
anInt = 23
print (“foo()'s globals:”, globals().keys())
print (“foo()'s locals:”, locals().keys())

foo()
print("**************")
print (“main’s globals:”, globals().keys())
print (“main’s locals:”, locals().keys())

执行结果:
main’s globals1: dict_keys([‘name’, ‘doc’, ‘package’, ‘loader’, ‘spec’, ‘annotations’, ‘builtins’, ‘file’, ‘cached’])
main’s locals1: dict_keys([‘name’, ‘doc’, ‘package’, ‘loader’, ‘spec’, ‘annotations’, ‘builtins’, ‘file’, ‘cached’])


calling foo()…
foo()'s globals: dict_keys([‘name’, ‘doc’, ‘package’, ‘loader’, ‘spec’, ‘annotations’, ‘builtins’, ‘file’, ‘cached’, ‘foo’])
foo()'s locals: dict_keys([‘anInt’, ‘aStr’])


main’s globals: dict_keys([‘name’, ‘doc’, ‘package’, ‘loader’, ‘spec’, ‘annotations’, ‘builtins’, ‘file’, ‘cached’, ‘foo’])
main’s locals: dict_keys([‘name’, ‘doc’, ‘package’, ‘loader’, ‘spec’, ‘annotations’, ‘builtins’, ‘file’, ‘cached’, ‘foo’])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值