码迷,mamicode.com
首页 > 编程语言 > 详细

python面向对象其他相关-异常处理-反射

时间:2015-12-15 01:03:55      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:

1.isinstance(obj, cls)

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

 

2.issubclass(sub, super)

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

n1 = 10
a1 = "123"
print type(n1)
print type(a1)
print isinstance(n1,int)            #判断n1是否属于int类型,正确返回True
print -->,isinstance(n1,str)      #判断n1是否属于str类型,正确返回True

class A:
    pass
class B(A):
    pass
a = B()
print isinstance(a,A)
print isinstance(a,B)
print issubclass(B,A)   #检查B类是不是A类的派生类
print issubclass(A,B)


执行结果:
<type int>
<type str>
True
--> False
True
True
True
False

 

3.异常处理

异常基础:

try:
    pass
except Exception,e:
    print e  #打印出异常内容
    pass

实例:

while True:
    num1 = raw_input(num1:)
    num2 = raw_input(num2:)
    try:
        num1 = int(num1)    #将输入内容转换为int类型
        num2 = int(num2)
        result = num1 + num2
    except Exception, e:
        print 出现异常,信息如下:    #当输入不为int类型,捕获异常
        print e

#运行
num1:1
num2:2
num1:d
num2:
3出现异常,信息如下:
invalid literal for int() with base 10: d
num1:1.1
num2:2
出现异常,信息如下:
invalid literal for int() with base 10: 31.1
在实际应用中,我们可能需要捕获一些特定的异常,最后的时候才捕获所有异常类型
#常用异常
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的

IndexError示例:

dic = ["ares", aaaa]
try:
    dic[10]
except KeyError,e:
    print e

#执行结果报错为
  File "XXX", line 6, in <module>
    dic[10]
IndexError: list index out of range

#更改捕获的错误类型
dic = ["ares", aaaa]
try:
    dic[10]
except IndexError, e:
    print e

#此时运行就捕获到了错误类型
list index out of range

KeyError示例:

dic = {k1:v1}
try:
    dic[k2]
except KeyError, e:
    print e

#捕获到的错误类型
k2

ValueError示例:

s1 = hello
try:
    int(s1)
except ValueError, e:
    print e

#捕获到的错误
invalid literal for int() with base 10: hello

如果是单纯的定义一个异常,则如果程序中出现其他异常就会报错,此时,我们可以捕获已知的异常类型,对于未知的异常类型可以用万能异常 Exception捕获。

s1 = hello
try:
    int(s1)
except KeyError,e:
    print 键错误
except IndexError,e:
    print 索引错误
except Exception, e:
    print 错误

异常结构:

try:
    #逻辑代码
    pass
except IndexError,e:
    pass
except Exception,e:
    pass
else:
    #逻辑串中未出现异常
    pass
finally:
    #释放资源,断开连接
    #永远执行,逻辑代码执行完之后执行
    pass

有时我们可能想要主动触发异常,方法如下

try:
    raise Exception(错误了。。。)
except Exception,e:
    print e

#输出结果
错误了。。。

自定义异常:

#自定义异常
class OwnerError(Exception):
    def __init__(self,msg=None):
        self.message = msg
    def __str__(self):
        if self.message:
            return self.message
        else:
            return Owner Error
try:
    raise OwnerError(erroreroor)
except Exception,e:
    print e

#输出内容
erroreroor

断言:

# assert 条件
assert 1 == 1
assert 1 == 2

#不太清楚,先记下

 

重头戏,反射来了。。。。。

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

示例1:输入不同url来实现不同跳转

#home.py函数
def dev():
    return "home/dev"
def index():
    return "home/index"
def login():
    return "home/login"
def logout():
    return "home/logout"

#调用home模块
import home
#输入不同url跳转
#第一种实现方式,使用if/else做判断
print "-------------------->"
while True:
    url = raw_input("input url:")
    if url == "home/dev":
        ret = home.dev()
        print ret
    elif url == "home/index":
        ret = home.index()
        print ret
    elif url == "home/login":
        ret = home.login()
        print ret
    elif url == "home/logout":
        ret = home.logout()
        print ret
    else:
        print "404"

#运行结果
-------------------->
input url:home/dev
home/dev
input url:home/login
home/login
input url:home/sad
404
可以看到,上述代码已经基本实现了我们的需求,即输入不同url来进行不同的跳转,但是,如果url有上万个,这么方式显然是不可取的,那么,应该怎么办呢???

其实,将上述代码稍作修改即可:

#第二种实现方式,使用getattr函数做反射
import home
print "-------------------->"
while True:
    url = raw_input("input url:")
#对输入的url从/进行切割,例如输入home/dev,那么controller即为home,function为dev
    controller,function = url.split(/)    
    #function为字符串
    #去某个函数(模块)中找函数,字符串函数名,若果有则获取函数
    func = getattr(home,function)
    ret = func()
    print ret

实例2:

#getattr,setattr,deleattr,hasattr,对内存某一个容器的元素做操作,只对内存做更改
#找到home文件,加载到内存
import home
print dir(home)
print hasattr(home,dev)   #判断home里是否存在dev方法
print hasattr(home,devv)
print getattr(home,dev)   #取出home里是否存在dev方法
setattr(home,ares,single)       #设置ares成员
print dir(home)
setattr(home,ares,lambda x:x+1)
print dir(home)
delattr(home,ares)        #删除ares成员
print dir(home)

#执行结果
[__author__, __builtins__, __doc__, __file__, __name__, __package__, dev, index, login, logout]
True
False
<function dev at 0x00000000027A1978>
[__author__, __builtins__, __doc__, __file__, __name__, __package__, ares, dev, index, login, logout]
[__author__, __builtins__, __doc__, __file__, __name__, __package__, ares, dev, index, login, logout]
[__author__, __builtins__, __doc__, __file__, __name__, __package__, dev, index, login, logout]

实例3:

class Foo:
    atatic_name = ares
    def __init__(self):
        self.name = ares
    def show(self):
        pass
    @staticmethod
    def static_show():
        pass
    @classmethod
    def class_show(self):
        pass

print Foo.__dict__.keys()
print hasattr(Foo,static_show)
obj = Foo()
print obj.__dict__
print obj.__dict__[name]      #将获取obj对象中的name变量指向内存中的值 “ares”
print hasattr(obj,name)
print hasattr(obj,show)
print getattr(obj,name)       #将获取obj对象中的name变量指向内存中的值 “ares”

#执行结果
[atatic_name, __module__, static_show, show, class_show, __doc__, __init__]
True
{name: ares}
ares
True
True
ares

web框架实例,可在浏览器执行localhost:8001/xxx:

from wsgiref.simple_server import make_server
def RunServer(environ, start_response):
    start_response(200 OK, [(Content-Type, text/html)])
    url = environ[PATH_INFO]
    temp = url.split(/)[1]            #获取http://localhost:8001/login的login字符串
    import home
    is_exist = hasattr(home, temp)      #去home模块中检查是否含有指定的函数
    if is_exist:                        #如果存在指定函数
        func = getattr(home, temp)      #获取函数
        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()

一切事物皆对象,类是对象,模块也是对象!

 

单例模式:

demo:

from wsgiref.simple_server import make_server
class DbHelper(object):
    def __init__(self):
        self.hostname = 1.1.1.1
        self.port = 3306
        self.password = pwd
        self.username = root
    def fetch(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return fetch
    def create(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return create
    def remove(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return remove
    def modify(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        return modify

class Handler(object):
    def index(self):
        # 创建对象
        db = DbHelper()
        db.fetch()
        return index
    def news(self):
        return news

def RunServer(environ, start_response):
    start_response(200 OK, [(Content-Type, text/html)])
    url = environ[PATH_INFO]
    temp = url.split(/)[1]
    obj = Handler()
    is_exist = hasattr(obj, temp)
    if is_exist:
        func = getattr(obj, temp)
        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()

上述实例,每个请求到来,都需要在内存里创建一个实例,再通过该实例执行指定的方法。如果并发量大的话,内存里就会存在非常多功能上一模一样的对象。存在这些对象肯定会消耗内存,对于这些功能相同的对象可以在内存中仅创建一个,需要时都去调用,这么可以省下不少的内存。

单实例模式就是用来解决这个问题的,单例模式用来保证内存中仅存在一个实例!!!

对于Python单例模式,创建对象时不能再直接使用:obj = Foo(),而应该调用特殊的方法:obj = Foo.singleton() ,上述代码可以修改成

#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server

# ########### 单例类定义 ###########
class DbHelper(object):

    __instance = None

    def __init__(self):
        self.hostname = 1.1.1.1
        self.port = 3306
        self.password = pwd
        self.username = root

    @staticmethod
    def singleton():
        if DbHelper.__instance:
            return DbHelper.__instance
        else:
            DbHelper.__instance = DbHelper()
            return DbHelper.__instance

    def fetch(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

    def create(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

    def remove(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass

    def modify(self):
        # 连接数据库
        # 拼接sql语句
        # 操作
        pass


class Handler(object):

    def index(self):
        obj =  DbHelper.singleton()
        print id(single)
        obj.create()
        return index

    def news(self):
        return news


def RunServer(environ, start_response):
    start_response(200 OK, [(Content-Type, text/html)])
    url = environ[PATH_INFO]
    temp = url.split(/)[1]
    obj = Handler()
    is_exist = hasattr(obj, temp)
    if is_exist:
        func = getattr(obj, temp)
        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()

总结:单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费!

更多请参考:http://www.cnblogs.com/wupeiqi/articles/5017742.html

python面向对象其他相关-异常处理-反射

标签:

原文地址:http://www.cnblogs.com/aresxin/p/5046923.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!