贴两个代码吧:
>>> from enum import Enum
>>> Month1=Enum('Month2',('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'))
>>> Month1.Jan #首先要注意这里的名字要与刚开始的Month1(就是等号前面的那个)保持一致,虽然我也不知道Enum()括号里面的Month2是干嘛的,,,,
1>
>>> Month2.Feb #你看,当使用Month2调用时就会出错
Traceback (most recent call last):
File "" , line 1, in
NameError: name 'Month2' is not defined
>>> Month1.Sep
9>
>>> for name,member in Month1.__members__.items(): #另外还可以使用for in循环进行遍历访问其中的元素
... print(name,'-->',member,member.value)
...
Jan --> Month2.Jan 1 分别是name(就是Enum括号里面的),member(就是Month1.name返回的值) 以及对应的member.value的值
Feb --> Month2.Feb 2
Mar --> Month2.Mar 3
Apr --> Month2.Apr 4
May --> Month2.May 5
Jun --> Month2.Jun 6
Jul --> Month2.Jul 7
Aug --> Month2.Aug 8
Sep --> Month2.Sep 9
Oct --> Month2.Oct 10
Nov --> Month2.Nov 11
Dec --> Month2.Dec 12
对于第二个例子,我们可以定义一个类,用来继承Enum
>>> from enum import Enum,unique
>>> @unique
... class Weekday(Enum):
... Sun=0
... Mon=1
... Thu=2
... Wed=3
... Thr=4
... Fri=5
... Sat=6
...
>>> Weekday.Mon
1>
>>> Weekday['Mon']
1>
>>> Weekday(1)
1>
最后写一个作业题:
“把Student的gender属性改造为枚举类型,可以避免使用字符串:”
>>> from enum import Enum,unique
>>> @unique
... class Gender(Enum):
... male=0
... female=1
...
>>> class Student(object):
... def __init__(self,name,gender):
... self.name=name
... self.gender=gender
...
>>> xuan=Student('Zhangxuan',Gender.female)
>>> xuan.gender==Gender.female
True
>>>
首先写一个hello.py文件(模块)
在里面写:
class Hello(object):
... def hello(self,name='Zhangxuan'):
... print("hello,%s."%name)
...
>>>
然后在右边的控制台输入:
from hello import Hello
h=Hello() #表明h是类Hello的一个实例
h.hello() #实例h调用方法(函数)hello()
hello,Zhangxuan.
type(Hello)
Out[158]: type #Hello是一个类 它的类型就是
type(h)
Out[159]: hello.Hello
那么如何通过type()函数动态创建类呢,type()函数可以返回一个对象的类型又可以创建出一个新的类型,比如我们可以通过type()函数创建出一个Hello类,而无需通过class Hello(object):….
代码如下:
>>> def fn(self,name='World'):
... print("Hello,%s."%name)
...
>>> Hello=type('Hello',(object,),dict(hello=fn))
>>> h=Hello()
>>> h.hello()
Hello,World.
>>> type(Hello)
'type'>
>>> type(h)
'__main__.Hello'>
>>>
```要想创建一个class类, type()函数需要传入三个参数:
1.类的名称
2.类所继承的类,注意tuple()中单个元素的写法需要加,
3.class里面的方法,这里我们吧函数fn绑定要方法hello上
这里写代码片
“`
>>> Hello1=type('Hello2',(object,),dict(hello=fn))
>>> h=Hello2() #所以要注意类是前面被赋值的那个Hello1!!! 而不是后面type()里面的,可是Hello2 我也不知道是干嘛的,,,
Traceback (most recent call last):
File "" , line 1, in <module>
NameError: name 'Hello2' is not defined
>>> h=Hello1()
>>> h.hello()
hello,Zhangxuan.
>>> type(Hello1)
<class 'type'>
>>> type(h)
<class '__main__.Hello2'>
需要掌握try..except…的用法:
def func(n):
try:
print("Trying....")
value=10/n
#print("the value is{}".format(value))
except ZeroDivisionError as e:
print("error",e)
else:
print("No error!")
print("the value is{}".format(value))
finally:
print("Finally.....")
def main():
func(10)
main()
其实也可以返回多个except 用来捕捉多种类型的错误:(比如ValueError,ZeroDivisionError等等)
def func(s):
try:
print("Trying!")
value=10/int(s)
print("the value is {}".format(value))
except ValueError as e:
print("error1:",e)
except ZeroDivisionError as e:
print("error2:",e)
finally:
print("Finally!")
def main():
#func('xixi') #会抛出第一种错误
func('0') #会抛出第二种错误
main()
如果遇到函数之间调用的只需要在恰当的函数里捕捉错误就可以了
def func1(s):
value=10/int(s)
return value
def func2(s): #func2 调用func1
return func1(s)*2
def main(): #main 函数调用func2
s='xixi'
#s='0'
try:
print("Trying!")
value=func2(s)+100
print("the value is {}".format(value))
except ValueError as e:
print("Error1:",e)
except ZeroDivisionError as e:
print("Error2:",e)
else:
print("There is no error!")
finally:
print("Finally!")
print('End!')
main()
当多个函数有调用关系时某一个函数可能出错,不需要在上级调用它的函数都一一捕捉,只需要在合适的层次捕捉错误就可以了
当我们不进行错误捕捉时,一旦在主函数中运行出错就不会再继续往下运行了,就像这样:
def func(s):
value=10/int(s)
return value
def func2(s):
return func(s)*2
def main():
s='0'
value=func2(s)
print("the value is {}".format(value))
print('End') #在控制台就没有输出,,,
main()
我们知道再main()函数的第一个print 语句打印value的值时就会运行出错,因为value本身有问题int(‘0’)返回一个0 func1里面计算10/int(‘0’)会出错,继而func2会出错,main()错
所以后面的print(‘End’)也不会被继续执行
报错信息如下:
File "E:/pyhtonworkspace/py3-pratice/bymyself_practice/python_Liaoxuefeng/20180211/hello.py", line 116, in
main()
File "E:/pyhtonworkspace/py3-pratice/bymyself_practice/python_Liaoxuefeng/20180211/hello.py", line 112, in main
value=func2(s)
File "E:/pyhtonworkspace/py3-pratice/bymyself_practice/python_Liaoxuefeng/20180211/hello.py", line 108, in func2
return func(s)*2
File "E:/pyhtonworkspace/py3-pratice/bymyself_practice/python_Liaoxuefeng/20180211/hello.py", line 104, in func
value=10/int(s)
ZeroDivisionError: division by zero
但是如果我们想让出错的同时抛出错误信息,同时程序可以继续运行,我们可以使用logging
import logging
def func(s):
value=10/int(s)
return value
def main():
try:
value=func('0')
print("the value is {}".format(value)) #这句可不会执行,因为本来try except 就是一旦try部分出现错 就不再继续执行 直接跳到except部分执行
except ZeroDivisionError as e:
logging.exception(e)
print('End!!看看我能不能输出') #当使用logging时 抛出错误时仍然会继续执行剩下的语句,保证程序继续执行
main(
控制台运行如下:
ERROR:root:division by zero
Traceback (most recent call last):
File "E:/pyhtonworkspace/py3-pratice/bymyself_practice/python_Liaoxuefeng/20180211/hello.py", line 128, in main
value=func('0')
File "E:/pyhtonworkspace/py3-pratice/bymyself_practice/python_Liaoxuefeng/20180211/hello.py", line 123, in func
value=10/int(s)
ZeroDivisionError: division by zero
End!!看看我能不能输出
可以看到这里只是把错误信息记录下来,并没有像之前那样抛出一些乱七八糟的错误信息(一看程序就出错的那种,其实自己可以运行上面两种函数对比一下控制台输出的形式),而且可以保证程序继续执行,所以会输出try except函数外的最后一条print语句
最后再写一个作业:
“运行下面的代码,根据异常信息进行分析,定位出错误源头,并修复:”
#这个程序是有错误的现在要根据这段错误代码抛出的异常信息,定位错误,并修改
from functools import reduce
def str2num(s):
return int(s)
def calc(exp):
ss = exp.split('+')
ns = map(str2num, ss)
return reduce(lambda acc, x: acc + x, ns)
def main():
r = calc('100 + 200 + 345')
print('100 + 200 + 345 =', r)
r = calc('99 + 88 + 7.6')
print('99 + 88 + 7.6 =', r)
main()
这段代码运行之后显示的错误如下:
File "E:/pyhtonworkspace/py3-pratice/bymyself_practice/python_Liaoxuefeng/20180211/hello.py", line 157, in
main()
File "E:/pyhtonworkspace/py3-pratice/bymyself_practice/python_Liaoxuefeng/20180211/hello.py", line 154, in main
r = calc('99 + 88 + 7.6')
File "E:/pyhtonworkspace/py3-pratice/bymyself_practice/python_Liaoxuefeng/20180211/hello.py", line 149, in calc
return reduce(lambda acc, x: acc + x, ns)
File "E:/pyhtonworkspace/py3-pratice/bymyself_practice/python_Liaoxuefeng/20180211/hello.py", line 144, in str2num
return int(s)
ValueError: invalid literal for int() with base 10: ' 7.6'
代码修改如下:
from functools import reduce
def str2num(s):
#return int(s) #这是原来的语句
try:
number=int(s)
except: #注意这个地方的写法 是在except里面再写一个try except 而不是并且的写except!!有点类似于if else 里面的嵌套if else
try:
number=float(s)
except:
print("what you input is not a number!!!")
finally:
return number
def calc(exp):
ss = exp.split('+') #这里是把calc()里面的字符串以+号分割 剩下的都是单个的字符 '100' ,'200' split之后返回的时list
ns = map(str2num, ss)#这里借助map函数把上面自己定义的str2num函数(也就是把字符转换成整数的函数)依次作用于ss这个由字符串组成的列表!
return reduce(lambda acc, x: acc + x, ns) #再使用reduce函数把两个数相加的函数依次作用于一个map返回的可迭代对象(里面全是数字类型的)
def main():
r = calc('100 + 200 + 345')
print('100 + 200 + 345 =', r)
r = calc('99 + 88 + 7.6')
print('99 + 88 + 7.6 =', r)
main()
然后再复习一下 split:
>>>
>>> s='100+200+300'
>>> L=s.split('+') #split之后返回的是一个列表
>>> L
['100', '200', '300']
>>>
回宿舍了