<--目录-->

1)反射的应用

2)装饰器

3)面像对像编程

4)异常处理


【反射的应用】

什么是反射?

1、以字符串的形式导入模块

2、以字符串的形式执行模块


示例1:

在main包下有demo.py模块和index.py模块

如下图

main
  - demo.py
  - index.py


cat demo.py
def Foo()
print 'demo.foo'


cat index.py
#!/usr/bin/env python
#coding:utf-8
str1 = 'demo'
str2 = 'Foo'
module = __import__(str1)  #import demo,以字符串的形式导入模块
func = getattr(module,str2)
func()   #以字符串形式执行函数


#执行脚本

python index.py
demo.foo


示例2:

reflect包下有一个backend包,和一个index.py模块

backend包下有两个模块account.py和admin.py模块

如下图:

reflect
   - backend包
- account.py
- admin.py
   - index.py


cat index.py
#!/usr/bin/env Python
#coding:utf-8
#执行规范 xxx/xxx
#account/login
data = raw_input('请输入地址:')   #account/login
array = data.split('/')   #['account','login']
userspance = __import__('backend.'+array[0]) #相当于import backend.account,这里可以理解成导入他的文件夹
model = getattr(userspance,array[0])  #这里可以理解成获得他的模块,
func = getattr(model,array[1])  #获得他的功能方法
func()   #执行函数


cat account.py
#!/usr/bin/env Python
#coding:utf-8
def login():
    print 'login'
def loginout():
    print 'loginout'


cat admin.py
#!/usr/bin/env Python
#coding:utf-8
def index():
    print '难迎登陆后台管理系统'
#执行脚本
python index.py
请输入地址:account/loginout
loginout



【装饰器】

示例1:

cat index.py
#!/usr/bin/env Python
#coding:utf-8
def outer(fun):
    def wrapper():      #装饰器函数
        print 'test1'  
        fun()
        print 'test2'        
    return wrapper      #返回该函数
    
@outer       #建立关系,代表 outer = outer(Func1)
def Func1():
    print 'func1'
    
@outer       #建立关系,代表 outer = outer(Func2)
def Func2():
    print 'func2'
    
Func1()
Func2()


#执行脚本

python index.py
test1
func1
test2
test1
func2
test2


示例2:

cat index.py
#!/usr/bin/env Python
#coding:utf-8
def outer(Func1):
    def wrapper(arg):      #装饰器函数
        print 'test1'  
        Func1(arg)
        print 'test2'        
    return wrapper      #返回该函数
    
@outer       #建立关系,代表 outer = outer(Func1)
def Func1(arg):
    print 'func1',arg
    
Func1('wsyht')


#执行函数

python index.py
test1
func1 wsyht
test2


示例3:

cat index.py
#!/usr/bin/env Python
#coding:utf-8
def outer(Func1):
    def wrapper(arg):      #装饰器函数
        print 'test1'  
        result = Func1(arg)   
        print 'test2'        
        return result
    return wrapper      #返回该函数
    
@outer       #建立关系,代表 outer = outer(Func1)
def Func1(arg):
    print 'func1',arg
    return 'success'
    
response = Func1('wsyht')
print response


#执行脚本

python index.py
test1
func1 wsyht
test2
success


【面向对像编程】

字段、方法、特性讲解

示例1:

#!/usr/bin/env Python
#coding:utf-8
class Province:  #class是类的定义,class后面是他的名称,有类就得要有init函数
    
    memo = '中国的23个省之一'   #静态字段属于类
    
    def __init__(self,name,capital,leader):  #__init__初始化,实例化动作提供的一个函数,self是关健字,必须要加,后面三个是接收的参数
        self.Name = name            #此三行是动态字段,属于对像
        self.Capital = capital      #把后面的Cpital赋值给self.Capital
        self.Leader = leader       
        
    def sports_meet(self):    #动态方法
        print self.Name + '正在开运动会'
        
    @staticmethod  #把动态反方转换成静态方法
    def Foo():   #静态方法属于类,括号不能加self
        print '每个省都带头反腐'
        
    @property      #property装鉓器,把方法转换成特性
    def Bar(self):
        print self.Name
        return 'somthing'
        
gd = Province('广东','广州','wsyht')    #创像三个对像,传到init函数self的后面三个值里面
hb = Province('山东','济南','张三')      #hb和上一行的gd可以理解成传给了self

 

#对像访问动态字段(推荐 使用)

print gd.Name,gd.Capital,gd.Leader
print hb.Name,hb.Capital,hb.Leader


#对像访问静态字段(不推荐使用)

print gd.memo


#类访问静态字段

print Province.memo


#类不能访问动态字段

#print Province.Name  

#为什么?

#因为动态字段只属于他相应的对像,所以类不能访问


#对像可以访问动态方法,类不可以访问动态访法,因为类不认识self

gd.sports_meet() 
hb.sports_meet()


#类访问静态方法

Province.Foo()


总结:

三种结构类型的数据

字段

  - 静态字段 (属于类,类可以访问静态字段,不可以访问动态字段)

  - 动态字段  (属于对像,对像可以访问动态字段,不可以访问静态字段)

方法

  - 静态方法  (属于类,类可以访问静态方法,不可以访问动态方法)

  - 动态方法   (对于对像,对像可以访问动态方法)

特性


#装饰器执行方法

gd.Bar        #调用特性,输出self.Name的值 
print gd.Bar     #此行输出的是return的值



动态方法和静态方法的区别:

动态方法演示:

cat index.py
#!/usr/bin/env python
#coding:utf-8
class MsSqlHelper:
    def add(self,sql):       #不需要实例化调用动态方法
        self.sql = sql
    def delete(self,sql):
        self.sql = sql
    def update(self,sql):
        self.sql = sql
    def select(self,sql):
        self.sql = sql
        
ms = MsSqlHelper()     #动态执行需要三行
ms.add('wsyht')
print ms.sql
ms = MsSqlHelper()
ms.delete('peter')
print ms.sql
ms = MsSqlHelper()
ms.update('jenkins')
print ms.sql
ms = MsSqlHelper()
ms.select('jim')
print ms.sql


#静态方法

#!/usr/bin/env python
#coding:utf-8
class MsSqlHelper:
    
    @staticmethod 
    def add(sql):
        print sql
        
    @staticmethod 
    def delete(sql):
        print sql
    
    @staticmethod 
    def update(sql):
        print sql
    
    @staticmethod 
    def select(sql):
        print sql
ms = MsSqlHelper()    #静态执行下面的内容只需要一行
ms.add('add')
ms.delete('sha')
ms.update('grane')
ms.select('cha')


公有方法和私有字段讲解:

#!/usr/bin/env Python
#coding:utf-8
#私有就是外部访问不到,内部访问得到
class Province:  #class是类的定义,class后面是他的名称,有类就得要有init函数
    
    def __init__(self,name,capital,leader,flag):  #__init__初始化,实例化动作提供的一个函数,self是关健字,必须要加,后面三个是接收的参数
        self.Name = name            #此三行是动态字段,属于对像
        self.Capital = capital      #把后面的Cpital赋值给self.Capital
        self.Leader = leader      
        self.__Thailand = flag   
    def show(self):    #私有字段,在内部可以访问得到
        print self.__Thailand
        
    @property   #property装鉓器,把方法转换成特性
    def Thailand(self):
        return self.__Thailand
        
    def __sha(self):  #私有方法
        print '我是wsyht'
    def Foo2(self):   #通过中间人调用上面的私有方法,
        self.__sha()
    
japan = Province('日本','东京','山本一夫','True')
 
japan.show()
print japan.Thailand
japan.Foo2()
#强制性调用私有方法(不建议用)
japan._Province__sha()



只读特性和只写特性

#!/usr/bin/env Python
#coding:utf-8
#私有就是外部访问不到,内部访问得到
class Province(object):  #class是类的定义,class后面是他的名称,有类就得要有init函数
    
    def __init__(self,name,capital,leader,flag):  #__init__初始化,实例化动作提供的一个函数,self是关健字,必须要加,后面三个是接收的参数
        self.Name = name            #此三行是动态字段,属于对像
        self.Capital = capital      #把后面的Cpital赋值给self.Capital
        self.Leader = leader      
        self.__Thailand = flag   
        
    #只读特性
    @property   #property装鉓器,把方法转换成特性 如果没有继随object那么这里是可读可写,如果继承了,那么这里就只是只读,如果还要写的话,那就还要写下面那三行只写特性
    def Thailand(self):
        return self.__Thailand
    
    #只改特性
    @Thailand.setter
    def Thailand(self,value):
        self.__Thailand = value  #value可以随便写
 
japan = Province('日本','东京','山本一夫','True')
print japan.Thailand       #读访问,特性不用加括号的,所以Thaiand后面不用加括号
japan.Thailand = False   #改
print japan.Thailand       #再输出查看


#没有继随object可读可写,继承了object,一个只读,一个只写,你要做两步操作



构造函数和构析函数

#!/usr/bin/env Python
#coding:utf-8
class Foo:
    def __init__(self):    #构造函数
        pass
    
    def __del__(self):     #析构函数,一般情况用不到,知道就好
        print '解释器要销毁我了'


__call__方法介绍:

#!/usr/bin/env Python
#coding:utf-8
class Foo:
    def Go(self):
        print 'Go'
        
    def __call__(self):  #__call__方法
        print 'call'
f1 = Foo()
f1.Go()  #非__call__方法执行方式
f1()   #执行f1()就是找call方法,执行类的__call__方法



类的继承:

#!/usr/bin/env Python
#coding:utf-8
class Father:
    def __init__(self):
        self.Fname = 'fff'
    def Func(self):
        print 'father.func'
    def Bad(self):
        print 'father,抽烟喝酒染发'
        
class Son(Father):  #子类继承父类
    def __init__(self):
        self.Sname = 'sss'
    def Bar(self):
        print 'son.bar'
        '''
    def Bad(self):   #重写父类的方法
        print 'son.抽烟喝酒不染发了'
        '''
    def Bad(self):
        Father.Bad(self)   #继承父类,然后重写
        print 'son,都戒了'


#父类(基类)、子类(派生类)

s1 =  Son()
s1.Bar()
s1.Func()
s1.Bad()

 



经典类和新式类的区别:

示例1:

#!/usr/bin/env Python
#coding:utf-8
class Father(object):
    def __init__(self):
        self.Fname = 'fff'
        print 'father.__init__'
        
    def Func(self):
        print 'father.func'
    def Bad(self):
        print 'father,抽烟喝酒染发'
        
class Son(Father):  #子类继承父类
    def __init__(self):
        self.Sname = 'sss'
        print 'son.__init__'
        #Father.__init__(self)  #调用父类的构造函数,不需要继承object,叫经典类
        super(Son,self).__init__()   #调用父类的构造函数,需要继承object,叫新式类
        #新式类比经典类要提供多一点内容
    def Bar(self):
        print 'son.bar'
        '''
    def Bad(self):   #重写父类的方法
        print 'son.抽烟喝酒不染发了'
        '''
    def Bad(self):
        Father.Bad(self)   #继承父类,然后重写
        print 'son,都戒了'


#父类(基类)、子类(派生类)

s1 =  Son()
s1.Bar()
s1.Func()
s1.Bad()


#推荐使用新式类,在Python2.2开始就产生新式类,2.2之前都是经典类,新式类兼容了经典类之前的功能,说白了经典类又在新式类的功能上加了新东西



示例2:多继承

class A(object):   #使用新式类继承方法
    def __init__(self):
        print 'This is A'
    def save(self):
        print 'save method from A'
        
class B(A):
    def __init__(self):
        print 'This is B'
        
class C(A):
    def __init__(self):
        print 'This is C'
    def save(self):
        print 'save method from C'
        
class D(B,C):  #从左到右执行,先执行B,再执行C
    def __init__(self):
        print 'This is D'
c = D()
c.save()



接口的定义,抽像类以及抽像方法

接口分为两种:

1、别人给你暴露一个URL,你去调用这个URL,这是其中一种接口的定义

2、就是先定义一个规范,然后去调用这个规范写出相应的功能就是接口


示例1:

interfack IAlert:  #只能指定规则,根据规范写内容,这只是举例子,实际上Python不存在interfack
    
    def __init__(self):
        pass     #在interface这个接口里不能写具体的实现,否则会报错
    def send(self):
        pass

#意义在于,有 这么一个接口,定义规范,根据规范写内容



#根据上面提供的一个接口,定义的规范写内容,

class Weixin(IAlert):
    def send(self):
        print '微信报警'
        
class Email(IAlert):
    def send(self):
        print '邮件报警'


示例2:

#!/usr/bin/env Python
#coding:utf-8
from abc import ABCMeta,abstractmethod
class Alert:   #抽像类,做接口,接口定义,做规范
    __metaclass__=ABCMeta
    
    @abstractmethod
    def Send(self):pass
    
class Weixin(Alert):   #继承抽像类
    def __init__(self):
        print '__init__'
    def Send(self):         #继承Send方法,也就是抽像方法
        print '微信报警'
f=Weixin()
f.Send()


总结:

抽像类加上抽像方法就等于接口,就是接口的功能用作规范



【异常处理】

1)Python提供好的异常处理

2)自定义异常和手动触发异常

常见异常

AttributeError对象没有这个属性

IOError        输入/输出操作失败

ImportError导入模块/对象失败

IndentationError缩进错误

IndexError序列中没有此索引(index)

KeyError映射中没有这个键

KeyboardInterrupt用户中断执行(通常是输入^C)

NameError未声明/初始化对象 (没有属性)

SyntaxErrorPython 语法错误

TabErrorTab 和空格混用

TypeError对类型无效的操作

UnboundLocalError访问未初始化的本地变量

ValueError传入无效的参数


例子:

使用except而不带任何异常类型

你可以不带任何异常类型使用except,如下实例:

try:
    正常的操作
   ......................
except 异常名字:
    发生异常,执行这块代码
   ......................
else:
    如果没有异常执行这块代码

以上方式try-except语句捕获所有发生的异常。但这不是一个很好的方式,我们不能通过该程序识别出具体的异常信息。因为它捕获所有的异常。


1、Python提供好的异常处理

示例:

#!/usr/bin/env Python
#coding:utf-8
data = raw_input('请输入地址:')   #account/login
array = data.split('/')   #['account','login']

try:
    #关健字
    #执行规范 xxx/xxx
    #account/login
    userspance = __import__('backend.'+array[0]) #相当于import backend.account
    model = getattr(userspance,array[0])  
    func = getattr(model,array[1])
    func()
        
#处理异常并捕捉
except (ImportError,AttributeError),e:  #捕捉两个异常  
    print '1,',e   #处理异常
    print '导入错误或属性错误'
except SyntaxError,e: #e代表SyntaxError这个对像的错误信息
    print 2,e           #e就是错误信息,输出ImportError的错误提示信息
    print '语法错误'
except Exception,e:  #用Exception是捕捉任何异常,或者不写Exception,直接写成except: 即可,这样更加方便
    print 3,e
    print '未知错误'
else:
    print '没有出错'
finally:
    print '无论异常与否,都会执行'


2、自定义异常和手动触发异常

示例1:

class MyException(Exception): 
    def __init__(self,msg):             #把自定义的错误信息传入msg
        self.error = msg
        
    def __str__(self,*args,**kwargs):   # __str__python自已提供的方法,用str方法来返回错误信息
        return self.error 
    
#obj = MyException('自定义错误信息')
#print obj

try:                  #如下为自定义异常
    raise MyException('自定义错误信息')  #用raise主动触发异常,然后就会执行下面那三行代码
except MyException,e:     
    print '写入日志到文件'
    print e  #输出自定义异常信息


示例2:

def Validate(name,pwd):
    if name == 'wsyht' and pwd == '123':
        return True
    else:
        return False
        
try:
    res = Validate('wsyht','324')
    if res:
        print 'login success...'
    else:
        #print '写入日志到文件'
        #print 'login fail' 
        raise Exception('登陆失败')  #用raise主动触发异常,然后就会执行下面那三行代码,如果有多个else的话,就可以少写很print
        
except Exception,e:  
    print '写入日志到文件'
    print e