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

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

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