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
其实,将上述代码稍作修改即可:
#第二种实现方式,使用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()
总结:单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费!