python面向对象编程(扩展) && python中的反射操作
一、isinstance(object,class)---判断object是否是class创建的对象
#1.示例1
n1 = 10 # ==== n1 = int(10) ,其实就是int类创建的对象 n1 =10 print isinstance(n1,int) #判断n1对象是否是int类创建的,返回True或则False
=================================================
结果:
True
#2、示例2:
class B(object): pass
obj = B() print isinstance(obj,B) =============================================================
结果:
True
#3.示例3
class A(object): pass class B(A): pass b = B() print isinstance(b,A) #返回True
#3.应用领域:在设计CMDB中从excel表导入数据的时候,系统会默认的将我们的整型数据转化为浮点型,而我们需要整型,这时候就要用到isinstance(object,class)
#eg1:伪代码
if isinstance(get_data,float): get_data = int(get_data)
二、issubclass(B,A) 判断B是否是A的子类
1.示例1
class A(object): pass class B(A): pass print issubclass(B,A) #返回结果True ======================================== 结果: True
三、try....except...的使用
(当用户在浏览器中输入错误时,我们就要用到异常处理(一般先捕获详细的异常,然后捕获万能异常))
用法:
try: #先执行code1 code1 #若code1发生异常时,就执行下面的代码及code2 except Execption,e: #e是Execption类创建的对象 code2
#示例0:
try: li = [12,3] print li[0] except Exception,e: print e try: li = [12,3] print li[3] except Exception,e: print e ============================================== 结果: 12 list index out of range
#示例1:自定义异常提示
try: input = raw_input() data = int(input) except Exception,e: print "plz input number" ================================================= 结果: input:adfasd plz input number
#示例2:单独捕获所有的异常错误
try: dic = {11:1,22:2} dic[1111] except Exception,e: #Exception可以捕获所有的错误 print 'error',e
#示例2:IndexError单独捕获索引错误
try: dic = {11:1,22:2} dic[1111] except IndexError,e: #IndexError可以捕获所有的错误 print 'Index error',e except KeyError,e: #IndexError可以捕获所有的错误 print 'Key error',e ===================================================== 结果: KeyError: 1111 #提示键索引错误
示例3:先捕获KeyError然后捕获IndexError错误,最后捕获Execption
try: dic = {11:1,22:2} dic[1111] except KeyError,e: #KeyError可以捕获key的错误 print 'key error',e except IndexError,e: #IndexError可以捕获Index的错误 print 'Index error',e except Exception,e: #万能的捕获错误信息 print e =========================================== 结果: Key error 1111
#示例4:主动触发异常,使用raise Exception("定义的异常语句") 来捕获异常
def f1(): pass if __name__== '__main__': try: n1 = "1" n = int(n1) ret = f1() if ret: print "success" else: #如果返回值为空就主动捕获自己定义的异常,传给e对象 raise Exception("get error") #主动捕获ret是False的异常,并封装到e中 except Exception,e: print u"出现错误,记录日志" print e
#示例5:终极异常处理(处理连接数据库的异常使用)
try: #逻辑代码:连接数据库,执行sql pass except IndexError,e: #异常时执行该模块 #code 记录日志 pass execept Execption,e: #异常时执行该模块 pass else: #逻辑代码执行完,没出现异常,执行此段代码 pass finally: #逻辑代码执行完之后,永远执行,不管是否出现异常, #code #断开数据库连接,释放资源 pass
#示例6:自定义异常
方法:
1.定义1个Error类,并且继承Exception类
2.并在类中定义2个函数:
__init__(self,msg=None)--用来接收类传进来的参数
__str__(self)---当用户调用CLASS()时即【类+括号】,其实就调用的类中的__str__(函数)
3、最后定义异常进行验证
验证1:
class JachyError(Exception): def __init__(self,msg=None): #定义msg为默认参数 self.message = msg def __str__(self): if self.message: #若用户传入了参数,就返回其传入的参数 return self.message else: return 'Jachy Error' #若没有传入,就返回自定义参数 try: raise JachyError('ADFAFA') #传入自定义参数 except Exception,e: print e =============================================== 结果: ADFAFA
注意:
try: int('asfdas') except Exception,e: #Exception类创建的对象e print e #打印的是一个对象,他是调用的是e.Exception中的__str__()方法
验证2:
class JachyError(Exception): def __init__(self,msg=None): self.message = msg def __str__(self): if self.message: return self.message else: return 'Jachy Error' try: raise JachyError('Jachy Error') except Exception,e: print e =================================== 结果: Jachy Error
验证3:
class HelloError(): def __str__(self): print "hello error" #自定义异常 pass try: obj = HelloError() except Exception,e: print obj
assert:断言---验证表达式是否为真
用法:
assert 表达式
含义:
若表达式为真,就不弹出错误;若表达式为假,弹出错误
assert 1==1 assert 1==2 结果: Traceback (most recent call last): File "E:/Code/Py.Code/PY4/day8/t1.py", line 284, in <module> assert 1>2 AssertionError
四、反射操作---通过操作内存中容器中的元素
包括4种方法:getattr(),setattr(),delattr(),hasattr()
getattr(MODULE,METHOD)----返回从MODULE文件中获取的METHOD方法
setattr(MODULE,METHOD,VALUE)----向文件MODULE文件中设置1个METOD方法,值为VALUE,但不写入文件只在内存中存在
delattr(MODULE,METHOD)-----删除MODULE文件中的METHOD方法
hasattr(MODULE,METHOD)----若MODULE文件中获取到了METHOD方法就返回True,否则返回False
下面是对比2种方法对用户输入的URL先进行判断,然后根据判断进行从文件中读取相应的方法
home.py文件
#!/usr/bin/env python # -*- coding:utf-8 -*- def dev1(): return "/home/dev1" def dev3(): return "/home/dev3" def dev2(): return "/home/dev2" def login1(): return "/home/login1"
#方式1
print "jachy.com" url = raw_input("input url:") import home if url == "/home/dev1": print home.dev1() elif url == "/home/dev2": print home.dev2() elif url == "/home/dev3": print home.dev3() elif url == "/home/login1": print home.login1() else: print "404"
#方式2
print "jachy.com" url = raw_input("url:") import home controller,action = url.split('/') #print controller func = getattr(home,action) #去home容器中找action函数 ret = func() print ret
示例3:运用has_attr(MODULE,METHOD)
import home url = raw_input("url:") func_name = url.split('/')[1] is_exist = hasattr(home,func_name) if is_exist: func = getattr(home,func_name) ret = func() print ret else: print "404 not found"
示例4:
import home print dir(home) #查看home模块中有哪些方法 #在内存中增加jachy方法 setattr(home,'jachy',lambda x:x+1) print dir(home) #删除home文件中的jachy方法 delattr(home,'jachy') print dir(home)
结果: ['Foo', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'dev1', 'dev2', 'dev3', 'login1'] ['Foo', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'dev1', 'dev2', 'dev3', 'jachy', 'login1'] ['Foo', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'dev1', 'dev2', 'dev3', 'login1']
反射扩展
示例5:反射操作中类和对象中的成员及hasattr(类,方法成员)或hasattr(对象,字段成员)
class Foo(object): static_name = 'lilin' def __init__(self): self.name = 'jachy' def show(self): pass @staticmethod def static_show(self): pass @classmethod def class_show(self): pass print Foo.__dict__ #查看Foo类中有哪些成员 print hasattr(Foo,'static_show') #查看Foo类中是否有static_show成员 obj = Foo() #显示obj对象里面所有的字段 print obj.__dict__ #显示:{'name': 'jachy'} #查看obj对象中是否含有'name'字段 print hasattr(obj,'name') #显示:True print hasattr(obj,'class_show')
结果: {'static_show': <staticmethod object at 0x00000000022A7C78>, '__module__': '__main__', '__init__': <function __init__ at 0x000000000272A4A8>, 'show': <function show at 0x000000000272A518>, '__dict__': <attribute '__dict__' of 'Foo' objects>, 'static_name': 'lilin', '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'class_show': <classmethod object at 0x0000000002658C18>} True {'name': 'jachy'} True True
示例6:反射操作的多层嵌套
1、定义home.py
def dev1(): return "/home/dev1" def dev3(): return "/home/dev3" def dev2(): return "/home/dev2" def login1(): return "/home/login1" class Foo(object): def __init__(self): self.name = 'jachy' def show1(self): pass
2、验证反射操作的嵌套成员
import home #在home模块中查找是否有Foo类成员,有就返回该类赋值给cls cls = getattr(home,'Foo') #在cls类中查找是否有show方法成员,有就返回True,否则返回False print hasattr(cls,'show') #返回False print hasattr(cls,'show1') #返回True 示例6:反射中模块的导入,__import__(模块)的应用 print "jachy.com" #获取模块和方法,并按'/'进行切分,分别封装到controller,action中 controller,action = raw_input("url:").split('/') #动态导入已经获取到的模块,并将其返回封装到module中 module = __import__(controller) #获取module中的action方法,并返回方法封装在func中 func = getattr(module,action) ret = func() #打印返回值 print ret
#我们的web框架的本质用反射来实现
#完整web框架的代码:
url = raw_input('url:') file_name = url.split('/')[0] func_name = url.split('/')[1] module = __import__(file_name) is_exist = hasattr(module,func_name) if is_exist: func = getattr(module,func_name) ret =func() print ret else: print "404 not found "
###设计模式(针对面向对象来讲)
##1.单例模式,顾名思义就是单个实例,就是永远只能创建1个实例
第1种:即类模板,创建实例,每个实例是不同角色
类方法、静态方法:不创建实例都能访问的方法
示例1:正常模式
class SqlHelper: def __init__(self): self.name = '0.0.0.0' self.port = 3306 self.user = 'root' self.pwd = '123' def get(self): return 1 pass def remove(self): pass obj1 = SqlHelper() print id(obj1) obj2 = SqlHelper print id(obj2)
#这种在内存里面就创建了多个实例,如果有若干个的话就会在内存中产生浪费
示例2:单例模式的定义示例
class SqlHelper: __static_instance = None def __init__(self): self.name = '0.0.0.0' self.port = 3306 self.user = 'root' self.pwd = '123' @classmethod def instance(cls): if cls.__static_instance: return cls.__static_instance else: cls.__static_instance = SqlHelper() return cls.__static_instance def get(self): return 1 pass def remove(self): pass obj1 = SqlHelper() print id(obj1) obj2 = SqlHelper print id(obj2)
#把实例放在内存中的自由字段里面,下次就可以直接使用这个实例而不用重新创建了。