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)
#把实例放在内存中的自由字段里面,下次就可以直接使用这个实例而不用重新创建了。
原文地址:https://www.cnblogs.com/jachy/p/5054597.html