Python学习笔记第八天

其他相关

isinstance

检查n1是否是int类型

举例:

n1 = 10
print isinstance(n1,int) #:类似type

True

检查对象b是否是类A的对象

class A:
    pass


class B(A):
    pass

b = B()
print isinstance(b,A)

True

issubclass

issubclass()方法判断某一个类是不是其他类的派生类

class A:
    pass

class B(A):
    pass

print issubclass(B,A)

执行结果:

True

异常处理

---如何优雅的处理(捕获)报错

为什么要做异常处理

在编写程序的过程在,为了增强程序对用户的友好性,在程序出现bug时一般不会将错误信息显示给用户,需要捕获错误信息并给用户返回一个相对友好的错误提示。

异常处理的常见格式:

try:
	pass

except Exception, e:
	pass

异常的种类

AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的

普通异常处理

#正常逻辑代码

try:

    #li = [11,22,33,44]
    #li['108']

    #dic = {'k1':'v1'}
    #dic['kkkk']

    #inp = 'windows'
    #data = int(inp)

#捕获异常代码块
except IndexError,e:

    #逻辑代码快出现错误
    print 'Error:',e
    #错误 可写入日志
    #第一段列表的错误捕获

except KeyError,e:

    #字典错误捕获
    print e

except Exception,e:

    #总错误捕获
    print e

代码说明:

正常逻辑代码里面有三个代码块,分别是列表,字典,字符串;去掉列表的注释后,则第一个捕获异常的代码块“IndexError”会被触发;注释好第一个逻辑代码块,然后去掉字典的注释,则第二个捕获异常的代码块“KeyError”则会被触发;

当逻辑代码块执行完毕,捕获异常的代码块触发第一个程序就退出了,不会再向下执行。

主动触发异常

说明:程序的逻辑代码里面又一个调用导入的模块“helper”执行的方法,若执行结果为True
打印“成功”,失败则“打印出自定义错误字符串”

import helper

if __name__ == '__main__':

    try:
        n = '你好整型'
        n = int(n)

        ret = helper.f1()
        if ret:
            print "成功"

        else:
            raise Exception('打印出自定义错误字符串')

    except Exception,e:

        print "出现错误"
        print e
        #print的 e是一个对象 调用的是Exception类里面的"__str__"方法

以下为模块文件helper.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#author = 'han'

def f1():
    return  False
    #程序出错啦,返回False

finally

数据库链接的例子:

说明:当执行完所有预定的操作方法之后,满足还没有任何异常被系统捕获,最后
使用“finally”方法断开连接释放远程资源

try:
    #逻辑代码
    pass
except IndexError,e:
    pass#若报错捕获

except Exception,e:
    pass#捕获

else:
    #若逻辑块未出现异常
    pass

finally:
    #断开链接释放资源
    #永远执行,逻辑代码执行完毕后执行
    pass

自定义异常

示例代码:

#继承Exception类
class WodeError(Exception):

    def __int__(self,msg=None):
        #默认错误
        self.message = msg

    #e是一个对象 调用的是这里Exception类里面的"__str__"方法
    def __str__(self):

        if self.message:
            return self.message

        else:
            return 'Error'

try:
    raise WodeError
    #raise WodeError('This is a self def Error')
    #如果有自定义错误存在 则优先抛出自定义错误“This is a self def Error” 去除前面注释则生效

except Exception,e:
    print e

断言

示例代码:

assert 1==2
#条件不成立 下面print不继续执行 抛错

print 'chenggong'
#当条件成立时候才执行print

反射

定义:反射是一种内存容器某个元素进行的一种操作

反射是以字符串导入模块 以字符串的形式执行函数

hasattr:查找函数是否存在
getattr:获取
setattr:增加
delattr:删除

!!!这些只是对读入内存的进行操作 reload文件后失效

getattr

定义:去某个容器(模块)中,找函数,如果有 则获取

需求:假设我们要实现一个web服务器,根据用户从浏览器请求过来的url返回对应的页面
假设用户请求是用raw_input输入

解决:下面分别使用传统方法和反射进行的实现:

home.py文件

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#author = 'han'

def p1():
    return 'p1'

def p2():
    return 'p2'

def p3():
    return 'p3'

def p4():
    return 'p4'

def p5():
    return 'p5'
逻辑方式:
import home

url = raw_input("f:")

if url == 'home/p1':
    ret = home.p1()
    print ret

elif url == 'home/p2':
    ret = home.p2()
    print ret

elif url == 'home/p3':
    ret = home.p3()
    print ret
反射方式
import home

url = raw_input("f:")

controller, action = url.split('/')

#获取对象,getattr接收到一个元祖(模块,执行动作)
func = getattr(home, action)

ret = func()

print ret

home.py 模块中包含函数p1,p2,p3,p4...

反射的WebDemo
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#author = 'han'

#!/usr/bin/env python
#coding:utf-8
#导入核心模块
from wsgiref.simple_server import make_server
import home


def RunServer(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    url = environ['PATH_INFO']
    functione_name = url.split('/')[1]
    #对url进行split

    is_exist = hasattr(home, functione_name)
    #去home模块中检查是否含有指定的函数
    if is_exist:
        #获取函数
        func = getattr(home, functione_name)
        #执行函数并获取返回值
        ret = func()
        return ret
        #将函数响应给请求者
    else:
        return '404 not found'

if __name__ == '__main__':
    httpd = make_server('', 8001, RunServer)
    print "Serving HTTP on port 8001..."
    httpd.serve_forever()

hasattr

import home
print hasattr(home, 'f1')

True

setattr

说明:导入模块,添加一个函数,setattr添加一个变量

#导入home模块
import home

添加一个函数
def p8():
    pass

#给函p8数添加变量‘alex'
setattr(home, 'alex',p8)

#获取变量,返回值内内存地址
print getattr(home, 'alex')
#判断是否有变量‘alex’
print hasattr(home, 'alex')

print dir(home) #setattr 多了个“alex”

执行结果

/usr/bin/python2.7 /home/han/PycharmProjects/oldboy_py/Day8/Note.py
<function p8 at 0x7f7569e317d0>
True
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'alex', 'p1', 'p2', 'p3', 'p4', 'p5']

Process finished with exit code 0

反射对类的操作

说明:

class Foo:
    static_name = 'nba'

    def __int__(self):
        self.name = 'alex'

    def show(self):
        pass

    @staticmethod
    def static_show():
        pass

    @classmethod
    def class_show(cls):
        pass

#print Foo.__dict__.keys() #打印类的成员名
#print hasattr(Foo, 'static_show')

obj = Foo()
print obj.__dict__
print hasattr(obj, 'name')
print hasattr(obj, 'show')




import home

controller, action = raw_input(':').split('/')

module = __import__(controller)
func = getattr(module,action)
ret =func
print ret


home/f1
<function f1 at 0x7fb5dc55b578>

设计模式

单例设计模式

内存中只存在一个实例

面向对象第二种
游戏,类模板,创建实例 每个实例是不同角色

面向对象第一种

class SqlHelper:
    __static_instance__ = None

    def __int__(self):

    @classmethod
    def instance(cls):
        if cls.__static_instance__:
            return cls.__static_instance__
        else:
            cls.__static_instance__ = SqlHelper()
            return cls.__static_instance__

    def fetch(self):
        pass
    def remove(self):
        pass


def get_user():

    obj = SqlHelper.instance()
    obj.fetch()
    print id(obj)
    return '1'

def del_user():
    obj = SqlHelper.instance()
    obj.remove()
    return '1'

Socket

web服务器示例

说明:运行代码,启动一个服务端socket,当浏览器访问时,返回"Hello, World"

#!/usr/bin/env python
#coding:utf-8
import socket

def handle_request(client):
    buf = client.recv(1024)
    #请求头文件
    client.send("HTTP/1.1 200 OK\r\n\r\n")
    #给客户端(特指浏览器)返回所需请求
    client.send("Hello, World")

def main():
    #创建socket对象
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    #监听端口
    sock.bind(('localhost',8080))
    #开始监听 “5”最大5个连接等待数
    sock.listen(5)

    while True:
        #阻塞状态,等待客户端的连接请求
        #直到有请求连接
        print '...'
        #connection代表客户端socket对象;address代表客户端IP地址
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()

if __name__ == '__main__':
  main()

模拟客户端与服务端通信

说明:服务端socket_s.py一直监听某端口等待客户端连接

如果有连接则返回请求给客户端

客户端socket_c.py发送数据给服务端并退出

服务端socket_s.py

import socket
print '.....'
obj_server = socket.socket()
obj_server.bind(('localhost',8080))
obj_server.listen(5)

while True:
    conn,addr = obj_server.accept()
    #最多接收的大小
    client_data = conn.recv(1024)
    print client_data
    conn.send('dddfwwwwww')
    #断开
    conn.close()

客户端socket_c.py

import socket

obj_client = socket.socket()

obj_client.connect(('localhost',8080))
obj_client.send('help')
server_data = obj_client.recv(1024)
obj_client.close()

处理并发的SocketServer

必须写一个类
继承SocketServer.BaseServer

import SocketServer

posted @ 2015-12-14 15:02  hallo.world  阅读(142)  评论(0)    收藏  举报