异常处理
异常在程序的运行过程中发生的不正常的事件,会中断正在运行的程序。
常见的内置异常
NameError 尝试访问一个未声明的变量
ZeroDivisionRrror 除数为零
SyntaxError 解释器语法错误
IndexError 请求的索引超出序列范围
KeyError 请求一个不存在的字典关键字
AttributeError 尝试访问未知的对象属性
异常结构
try:
语句 #被监控异常的代码块
except:
语句 #异常处理的代码
finally:#通常用来释放占用的资源,例如:关闭文件,关闭数据库的链接
例子1:
num1 = int(input("第一个整数:"))
num2 = int(input("第一个整数:"))
try:
shang = num1 / num2
print("{0}/{1}={2}".format(num1,num2,shang))
except Exception as eo :
print("有错误了{0}".format(eo))
finally:
print("感谢使用")
例子2:
num1 = int(input("第一个整数:"))
num2 = int(input("第一个整数:"))
try:
shang = num1 / num2
print("{0}/{1}={2}".format(num1,num2,shang))
except (TypeError,ZeroDivisionError) as eo :
print("有错误了{0}".format(eo))
finally:
print("感谢使用")
异常继承结构
BaseException类是所有异常之母,
Exception类是其他异常子类的父类
例子
多重异常判断
def aaa(obj):
try:
retval = float(obj)
except ValueError as e:
retval = "非数值类型数据不能转换为float数据"
except TypeError as e:
retval = "数据类型不能转换为float类型"
except Exception as e:
retval = "有异常"
return retval
print aaa("Hello world")
print aaa("599.99")
print aaa(200)
print aaa(99.9)
抛出异常
在什么场合抛出异常?
除了系统自动抛出异常外,在s编程过程中,有些问题是系统无法发现并解决的,
例如程序要求文件名不能是“hello”,此时需要程序员自行抛出异常,把问题交给调用者解决,通过抛出异常,接收兵处理异常,实现程序的多分支处理
raise语句格式很多,常用格式
raise 异常类
raise 异常类(参数或元组)
例子:(不能输入“等等”这个名字,如果输入了等等这个名字会抛出异常)
def filename():
filename = raw_input("Please input file name:")
if filename == "等等":
raise NameError("不能输入此姓名")
return filename
while True:
try:
filename=filename()
print "filename is %s"%filename
break
except NameError:
print "请换一个名字重新输入:"
多线程
由于每个进程只要干一件事,所以,一个进程只要有一个线程,当然,想Word这种复杂的进程可以有多个线程,多个线程可以同时执行,多线程的执行方式和多线程是一样的,也是由操作系统在多个线程之间快速切换,让每个线程都短暂得交替运行,看起来就像同时执行一样
1.新建状态(New):
当用new操作符创建一个线程时, 例如new Thread(r),线程还没有开始运行,此时线程处在新建状态。 当一个线程处于新生状态时,程序还没有开始运行线程中的代码
2.就绪状态(Runnable)
一个新创建的线程并不自动开始运行,要执行线程,必须调用线程的start()方法。当线程对象调用start()方法即启动了线程,start()方法创建线程运行的系统资源,并调度线程运行run()方法。当start()方法返回后,线程就处于就绪状态。
处于就绪状态的时候,并不是立即运行run()方法,而是线程同其他线程竞争CPU时间,获得CPU时间后才能运行,在单CPU的计算机系统中,不能同时运行多个线程,一个时刻只能有一个线程运行。所以,其他线程处于等待,
3.运行状态(Running)
当线程获得CPU时间后,它就可以进入运行状态,真正开始执行run()方法了.
4.阻塞状态(Blocked)
线程运行过程中,可能由于各种原因进入阻塞状态:
(1)>线程通过调用sleep方法进入睡眠状态;
(2)>线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
(3)>线程试图得到一个锁,而该锁正被其他线程持有;
(4)>线程在等待某个触发条件;
5.死亡状态(Dead)
有两个原因会导致线程死亡:
1) run方法正常退出而自然死亡,
2) 一个未捕获的异常终止了run方法而使线程猝死。
线程操作涉及到的方法:(详细请查看http://www.cnblogs.com/tkqasn/p/5700281.html)
对象:
类 方法
Tread: start 启动 join 加入新线程
Lock、Rlock: acquire枷锁 release释放锁
Condition: acquire枷锁 release释放锁 wait notify notif_all
Event: set等同于notifAll clear取消notifAll
timer: sleep等同于java的sleep
Python3 线程中常用的两个模块为:
1._thread
2.threading(推荐使用)
thread 模块已被废弃。用户可以使用 threading 模块代替。所以,在 Python3 中不能再使用”thread” 模块。为了兼容性,Python3 将 thread 重命名为 “_thread”。
例子1:(这是一个简单的线程练习)
import threading #导入模块threading
import time #导入模块time
a=threading.Lock() #获取枷锁
ca=threading.Condition(a) #给枷锁设置时间
def zheng():
for i in range(1,31):
print("zheng i={0}".format(i)) #从正序输出1-31
if i > 10:
ca.acquire() #如果i>10 给ca上锁
ca.notify() #唤醒ca
ca.release() #释放枷锁ca
if i > 25:
t2.join() #如果i>25,开始输出反序
time.sleep(0.1) #每输出一个睡一秒
def fan():
ca.acquire() #ca上枷锁
ca.wait() #ca等待同时释放枷锁
ca.release() #释放枷锁ca
for i in range(30,0,-1):
print("fan i={0}".format(i)) #从正序输出1-31
time.sleep(0.1) #每输出一个睡一秒
threading._start_new_thread(zheng,()) #创建线程
#threading._start_new_thread(fan,())
t2=threading.Thread(target=fan) #创建线程
t2.start() #开始ts的线程
input()
例子2:
一共4个人和尚,其中一个做馒头,其他三个吃馒头,
要求:
1.当做馒头的时候,不能吃馒头
2.当吃馒头的时候不能做馒头
3.馒头上线30个
4.再吃馒头的时候不能出现一个馒头被多个和尚吃
5.不能出现吃的时候和尚吃出异常(如一个和尚永远也吃不上,或者一个和尚吃了一个不存在的馒头)
这个是Python版的吃馒头的,下面还有一版java版的
import threading
import time
mantous=[]
a=threading.Lock()
b=threading.Lock()
ca=threading.Condition(a)
cb=threading.Condition(b)
#伙夫的任务函数
def huofu(name):
time.sleep(1)
while True:
ca.acquire()
for i in range(1,31):
mantous.append("第{0}个馒头".format(i))
print("做好{0}个馒头".format(i))
time.sleep(0.1)
print("馒头做好了,叫醒吃货")
ca.notify_all()
ca.release()
print("{0}去等待".format(name))
cb.acquire()
cb.wait()
cb.release()
#吃货的任务函数
def chihuo(name):
ca.acquire()
ca.wait()
ca.release()
while True:
m=None
ca.acquire()
if len(mantous)!=0:
m=mantous.pop()
else:
print("没馒头了")
cb.acquire()
cb.notify()
cb.release()
ca.wait()
ca.release()
if m is not None:
print("{0}吃{1}".format(name,m))
time.sleep(1)
threading._start_new_thread(huofu,('大头和尚',))
threading._start_new_thread(chihuo,('白眉和尚',))
threading._start_new_thread(chihuo,('牛鼻子和尚',))
threading._start_new_thread(chihuo,('花和尚',))
input()
java版的吃馒头
package com.dsj101.thread;
import java.util.ArrayList;
import java.util.List;
public class Test {
static class ManTou{
private int num;
public ManTou(int num) {
this.num = num;
}
@Override
public String toString() {
return "第"+num+"个";
}
}
public static List<ManTou> manTous=new ArrayList<>();
public static void main(String[] args) {
new HuoFu("大头和尚").start();
new ChiHuo("白眉和尚").start();
new ChiHuo("牛逼和尚").start();
new ChiHuo("花和尚").start();
}
//火夫
static class HuoFu extends Thread{
private String name;
public HuoFu(String name) {
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
while (true) {
synchronized ("a") {
System.out.println(name + "开始蒸馒头");
for (int i = 0; i < 30; i++) {
manTous.add(new ManTou(i + 1));
System.out.println("做完第" + (i + 1) + "个码头");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("馒头做好了,开始吃吧");
"a".notifyAll();
}
synchronized ("b") {
try {
System.out.println("我先去睡一会,没了叫我");
"b".wait();
System.out.println("我知道了开始做去");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
//吃货
static class ChiHuo extends Thread{
private String name;
public ChiHuo(String name) {
this.name = name;
}
@Override
public void run() {
synchronized ("a"){
try {
"a".wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
ManTou m=null;
while (true) {
synchronized ("a") {
System.out.println(name + "开始吃馒头");
if (manTous.size() != 0) {
m = manTous.remove(0);
} else {
System.out.println(name + "发现没有馒头,叫醒火夫做馒头");
synchronized ("b"){
"b".notify();
}
try {
System.out.println("我等着呢,完事后叫我吃");
"a".wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (m != null) {
System.out.println(name + "消化馒头"+m.toString());
int rd = (int) (Math.random() * 2000 + 1000);
m = null;
try {
Thread.sleep(rd);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}