一、反射及相关

  1.isinstance(obj, cls)

  检查是否obj是否是类 cls 的对象

class Foo(object):
pass obj = Foo() isinstance(obj, Foo)

  2.issubclass(sub, super)

  检查sub类是否是 super 类的派生类

class Foo(object):
pass class Bar(Foo):
pass issubclass(Bar, Foo)

  3.反射

  python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

 class Foo(object):

     def __init__(self):
self.name = 'wupeiqi' def func(self):
return 'func' obj = Foo() # #### 检查是否含有成员 ####
hasattr(obj, 'name')
hasattr(obj, 'func') # #### 获取成员 ####
getattr(obj, 'name')
getattr(obj, 'func') # #### 设置成员 ####
setattr(obj, 'age', 18)
setattr(obj, 'show', lambda num: num + 1) # #### 删除成员 ####
delattr(obj, 'name')
delattr(obj, 'func')
obj.name有三种访问方式
obj.name
obj.__dict__['name']
getattr(obj, 'name')

  结论:反射是通过字符串的形式操作对象相关的成员。一切事物都是对象!!!

 #!/usr/bin/env python
# -*- coding:utf-8 -*- import sys def s1():
print 's1' def s2():
print 's2' this_module = sys.modules[__name__] hasattr(this_module, 's1')
getattr(this_module, 's2')
 class Foo(object):

     staticField = "old boy"

     def __init__(self):
self.name = 'wupeiqi' def func(self):
return 'func' @staticmethod
def bar():
return 'bar' print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')

反射类的字段

二、异常处理

  在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!

while True:
num1 = raw_input('num1:')
num2 = raw_input('num2:')
try:
num1 = int(num1)
num2 = int(num2)
result = num1 + num2
except Exception, e:
print '出现异常,信息如下:'
print e
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
 ArithmeticError
AssertionError
AttributeError
BaseException
BufferError
BytesWarning
DeprecationWarning
EnvironmentError
EOFError
Exception
FloatingPointError
FutureWarning
GeneratorExit
ImportError
ImportWarning
IndentationError
IndexError
IOError
KeyboardInterrupt
KeyError
LookupError
MemoryError
NameError
NotImplementedError
OSError
OverflowError
PendingDeprecationWarning
ReferenceError
RuntimeError
RuntimeWarning
StandardError
StopIteration
SyntaxError
SyntaxWarning
SystemError
SystemExit
TabError
TypeError
UnboundLocalError
UnicodeDecodeError
UnicodeEncodeError
UnicodeError
UnicodeTranslateError
UnicodeWarning
UserWarning
ValueError
Warning
ZeroDivisionError 更多异常
 try:
raise Exception('错误了。。。')
except Exception,e:
print e
 class WupeiqiException(Exception):

     def __init__(self, msg):
self.message = msg def __str__(self):
return self.message try:
raise WupeiqiException('我的异常')
except WupeiqiException,e:
print e
# assert 条件

assert 1 == 1

assert 1 == 2

三、线程

  线程是最小工作单位,进程是资源池。

  1.直接调用

 import threading
import time def sayhi(num): #定义每个线程要运行的函数 print("running on number:%s" %num) time.sleep(3) if __name__ == '__main__': t1 = threading.Thread(target=sayhi,args=(1,)) #生成一个线程实例
t2 = threading.Thread(target=sayhi,args=(2,)) #生成另一个线程实例 t1.start() #启动线程
t2.start() #启动另一个线程 print(t1.getName()) #获取线程名
print(t2.getName())
 import threading
import time class MyThread(threading.Thread):
def __init__(self,num):
threading.Thread.__init__(self)
self.num = num def run(self):#定义每个线程要运行的函数 print("running on number:%s" %self.num) time.sleep(3) if __name__ == '__main__': t1 = MyThread(1)
t2 = MyThread(2)
t1.start()
t2.start()
#_*_coding:utf-8_*_

import time
import threading def run(n): print('[%s]------running----\n' % n)
time.sleep(2)
print('--done--') def main():
for i in range(5):
t = threading.Thread(target=run,args=[i,])
t.start()
t.join(1)
print('starting thread', t.getName()) m = threading.Thread(target=main,args=[])
m.setDaemon(True) #将main线程设置为Daemon线程,它做为程序主线程的守护线程,当主线程退出时,m线程也会退出,由m启动的其它子线程会同时退出,不管是否执行完任务
m.start()
m.join(timeout=2)
print("---main thread done----")
    • start            线程准备就绪,等待CPU调度
    • setName      为线程设置名称
    • getName      获取线程名称
    • setDaemon   设置为后台线程或前台线程(默认)
                         如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止
                          如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
    • join              逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
    • run              线程被cpu调度后自动执行线程对象的run方法

  2.线程锁(Lock、RLock)

    由于线程之间是进行随机调度,并且每个线程可能只执行n条执行之后,当多个线程同时修改同一条数据时可能会出现脏数据,所以,出现了线程锁 - 同一时刻允许一个线程执行操作。

 #!/usr/bin/env python
# -*- coding:utf-8 -*-
import threading
import time gl_num = 0 def show(arg):
global gl_num
time.sleep(1)
gl_num +=1
print(gl_num) for i in range(10):
t = threading.Thread(target=show, args=(i,))
t.start() print('main thread stop')

未使用锁

 #!/usr/bin/env python
#coding:utf-8 import threading
import time gl_num = 0 lock = threading.RLock() def Func():
lock.acquire()
global gl_num
gl_num +=1
time.sleep(1)
print(gl_num)
lock.release() for i in range(10):
t = threading.Thread(target=Func)
t.start()
print("main thread stop")

使用锁

   3.信号量(semaphore)

     互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去

  

  4.事件(event)

  python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。

  事件处理的机制:全局定义了一个“Flag”,如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,

  那么event.wait 方法时便不再阻塞。

  clear 将flag设置为False

  set 将flag设置为True

 import threading

 def do(event):
print 'start'
event.wait()
print 'execute' event_obj = threading.Event()
for i in range(10):
t = threading.Thread(target=do, args=(event_obj,))
t.start() event_obj.clear()
inp = raw_input('input:')
if inp == 'true':
event_obj.set()

  5.条件(Condition)

   使得线程等待,只有满足某条件时,才释放n个线程

 import threading

 def run(n):
con.acquire()
con.wait()
print("run the thread: %s" %n)
con.release() if __name__ == '__main__': con = threading.Condition()
for i in range(10):
t = threading.Thread(target=run, args=(i,))
t.start() while True:
inp = input('>>>')
if inp == 'q':
break
con.acquire()
con.notify(int(inp))
con.release()

  6.线程池

 from concurrent.futures import ThreadPoolExecutor
import requests def task(url):
response = requests.get(url)
print("得到结果:", url, len(response.content)) url_list = [
'http://www.baidu.com',
'http://www.sina.com.cn',
'http://www.autohome.com.cn'
] pool = ThreadPoolExecutor(2) for url in url_list:
print("请求开始", url)
pool.submit(task, url)

 

四、进程

 from multiprocessing import Process
import threading
import time def foo(i):
print('say hi',i) for i in range(10):
p = Process(target=foo, args=(i,))
p.start()

注意:由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。

 

  1.进程数据共享

  进程各自持有一份数据,默认无法共享数据

 from multiprocessing import Process

 import time

 li = []

 def foo(i):
li.append(i)
print('say hi',li) for i in range(10):
p = Process(target=foo, args=(i,))
p.start() print 'ending',li
 #方法一,Array
from multiprocessing import Process,Array temp = Array('i', [11,22,33,44]) def Foo(i):
temp[i] = 100+i
for item in temp:
print i,'----->',item for i in range(2):
p = Process(target=Foo, args=(i,))
p.start()

方法一

 #方法二:manage.dict()共享数据
from multiprocessing import Process,Manager manage = Manager()
dic = manage.dict() def Foo(i):
dic[i] = 100+i
print(dic.values()) for i in range(2):
p = Process(target=Foo, args=(i,))
p.start()
p.join()

方法二

  2.进程锁  

 from multiprocessing import Process, Array, RLock

 def Foo(lock, temp, i):
"""
将第0个数加100
"""
lock.acquire()
temp[0] = 100+i
for item in temp:
print(i,'----->',item)
lock.release() lock = RLock()
temp = Array('i', [11, 22, 33, 44]) for i in range(20):
p = Process(target=Foo, args=(lock, temp, i,))
p.start()

  3.进程池

 from concurrent.futures import ProcessPoolExecutor

 def task(arg):
print(arg)
return arg + 100 def call(arg):
data = arg.result()
print(data) if __name__ == '__main__':
pool = ProcessPoolExecutor(5)
for i in range(10):
obj = pool.submit(task, i)
obj.add_done_callback(call)

五、协程

  线程和进程的操作是由程序触发系统接口,最后的执行者是系统;协程的操作则是程序员。

  协程存在的意义:对于多线程应用,CPU通过切片的方式来切换线程间的执行,线程切换时需要耗时(保存状态,下次继续)。

  协程,则只使用一个线程,在一个线程中规定某个代码块执行顺序。

  协程的适用场景:当程序中存在大量不需要CPU的操作时(IO),适用于协程;

  1.greenlet

 from greenlet import greenlet

 def test1():
print(12)
gr2.switch()
print(34)
gr2.switch() def test2():
print(56)
gr1.switch()
print(78) gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

  2.gevent

 from gevent import monkey;monkey.patch_all()
import gevent
import requests def f(url):
print('GET: %s' % url)
resp = requests.get(url)
print('%s bytes received from %s' % (resp.status_code, url)) gevent.joinall([
gevent.spawn(f, 'http://www.baidu.com/'),
gevent.spawn(f, 'http://www.sina.com.cn/'),
])

python16_day08【异常、多线程】的更多相关文章

  1. Java基础 匿名内部类 异常 多线程 集合面试题

    匿名内部类:没有名字的内部类.就是内部类的简化形式.一般只用一次就可以用这种形式.匿名内部类其实就是一个匿名子类对象.想要定义匿名内部类:需要前提,内部类必须继承一个类或者实现接口. 匿名内部类的格式 ...

  2. 编写高质量代码改善C#程序的157个建议——建议66:正确捕获多线程中的异常

    建议66:正确捕获多线程中的异常 多线程的异常处理需要采用特殊的方式.一下这种方式会存在问题: try { Thread t = new Thread((ThreadStart)delegate { ...

  3. Java基础总结--多线程总结1

    ----进程和线程-----1.概述:简单理解一个进程就是一个正在运行的程序(程序在内存中的所属空间)程序只有在运行的时候才会被加载进内存2.进程内部的划分进程不会直接执行,只是被当作分配内存资源的基 ...

  4. Java-Thread00之多线程知识准备

    ------ ![](https://img2018.cnblogs.com/blog/1822322/201910/1822322-20191012170014292-1661101986.jpg) ...

  5. C#规范整理·异常与自定义异常

    这里会列举在C#中处理CLR异常方面的规范,帮助大家构建和开发一个运行良好和可靠的应用系统. 前言   迄今为止,CLR异常机制让人关注最多的一点就是"效率"问题.其实,这里存在认 ...

  6. C#多线程(13):任务基础①

    目录 多线程编程 多线程编程模式 探究优点 任务操作 两者创建任务的方式 Task.Run() 创建任务 取消任务和控制任务的创建 任务返回结果以及异步获取返回结果 捕获任务异常 全局捕获任务异常 多 ...

  7. 201521123083 《Java程序设计》第10周学习总结

    1. 本周学习总结 2. 书面作业 本次PTA作业题集异常,多线程 1.finally题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中finally中捕获异常需要注意什么? 一个tr ...

  8. 2018年如何快速学Java

    前言 只有光头才能变强 提前预警:本文适合Java新手阅读(老手可在评论区给下建议),希望大家看完能有所收获. 一.为什么我要写下这篇文章 1.1直接缘由: 在今天(2018年11月4日)有个同学给我 ...

  9. c# Task 篇幅二

    上面一篇https://i.cnblogs.com/EditPosts.aspx?postid=10444773我们介绍了Task的启动,Task的一些方法以及应用,今天我们着重介绍一下Task其它概 ...

  10. Java学习路线图(如何快速学Java)

    不知不觉从初学Java到现在已经8年了,今天在这里给刚入门和入门不久的小伙伴们一些建议.可能总结的不是很详细,但给出了一个大概的学习路线.希望对大家有帮助哈~ 如何快速学Java 这里我以Java E ...

随机推荐

  1. [Android] Ubuntu下Eclipse || Android Studio识别不了手机的官方解决方案

    最近在转移开发平台,Android Studio一直都识别不了手机,但Eclipse却可以.经过一番调查后,发现是自己一点所以然导致的.接下来直接奉上解决教程 解决教程 在命令行终端输入lsusb命令 ...

  2. CSS3自定义滚动条样式 -webkit-scrollbar (一)

    Webkit支持拥有overflow属性的区域,列表框,下拉菜单,textarea的滚动条自定义样式.当然,兼容所有浏览器的滚动条样式目前是不存在的. 滚动条的组成: ::-webkit-scroll ...

  3. 如何获得<div id=”div1”>This is first layer</div>中的值?

    如何获得<div id=”div1”>This is first layer</div>中的值? 解答: <script> var div1=Document.ge ...

  4. 解决使用VS2013创建的MVC项目在VS2015中打开的各种问题

    其实很多问题一直都存在,但是因为其不影响编译结果和运行结果,所以我也就一直没理它.但是问题放在那一直存在,偶尔想起来还有某些问题没解决的时候心里总是感觉不得劲,所以今天就彻底的查查资料解决了. 问题一 ...

  5. (转)Apache Mina网络框架

    转自1:整体结构分析 http://www.cnblogs.com/xuekyo/archive/2013/03/06/2945826.html 转自2:详细源码分析 http://www.cnblo ...

  6. (转)java 静态内部类

    转自:http://blog.sina.com.cn/s/blog_605f5b4f0100zbps.html 参考:http://docs.oracle.com/javase/tutorial/ja ...

  7. Dynamics CRM 系统自己定义部分的语言翻译

    Dynamics CRM 自带语言切换功能,在官网下载所需语言包安装后,在设置语言中就能看到你所加入的语言.勾选要启用的语言应用就可以.再打开系统设置--语言就能看到可更改用户界面语言的显示了. wa ...

  8. 第0步:OracleRAC软件准备

    表1   软件准备列表 安装包属性 文件信息 Oracle 11.2.0.4 p13390677_112040_Linux-x86-64_1of7.zip   p13390677_112040_Lin ...

  9. ajax利用html5新特性带进度条上传文件

    http://blog.csdn.net/pkgray/article/details/27591283 http://www.matlus.com/html5-file-upload-with-pr ...

  10. shell基础(二)

    echo命令 Shell 的 echo 指令是用于字符串的输出. #!/bin/sh read name #读取标准输入的行 echo "$name It is a test" e ...