python-裝飾器,類與對象,私有字段,析構,__call__,繼承,多繼承,接口

1、裝飾器執行流程

裝飾器可用於權限管理;

裝飾器:將原函數替換爲wrapper函數

def outer()
@outer  --- func1作爲參數傳入outer()
def wrapper()  --- wrapper()放入內存
return wrapper   --- 返回wrapper地址,Func1重新賦值爲wrapper
Func1()  --- 調用func1函數
def wrapper()
print '驗證'
def Func1()
print 'func1'
[root@localhost decorate]# python main.py 
驗證
func1
驗證
func2
[root@localhost decorate]# cat main.py 
#!/usr/bin/python27
#coding:utf-8

def outer(fun):
    def wrapper():
        print '驗證'
        fun()
    return wrapper

@outer
def Func1():
    print 'func1'

@outer
def Func2():
    print 'func2'

'''
Func1=
def wrapper():
    print '驗證'
    fun()
'''

Func1()
Func2()
[root@localhost decorate]#


帶參數的裝飾器

[root@localhost decorate]# python27 main1.py
驗證
func1 alex
[root@localhost decorate]# cat main1.py
#!/usr/bin/python27
#coding:utf-8

def outer(fun):
    def wrapper(arg):
        print '驗證'
        fun(arg)
    return wrapper

@outer
def Func1(arg):
    print 'func1',arg

'''
Func1=
def wrapper(arg):
    print '驗證'
    fun(arg)
'''

Func1('alex')
[root@localhost decorate]#


在函數執行的前後,執行任意函數

def Filter(before_func,after_func): 
    def outer(main_func):
         def wrapper(request,kargs): 
            before_result = before_func(request,kargs)
            if(before_result != None): 
                return before_result;
  
            main_result = main_func(request,kargs)
            if(main_result != None):
                return main_result;
  
            after_result = after_func(request,kargs)
            if(after_result != None):
                 return after_result;

         return wrapper
     return outer 

@Filter(AccountFilter.Before, AccountFilter.After) def List(request,kargs):
  pass



2、類與對象

封裝性:將name,age屬性封裝到self中


內存圖


類的內存:                               對象的內存

      |                                                 |

靜態字段                            動態字段:self.name

動態方法、靜態方法   --->引用      方法

[root@localhost ~]# python27 index.py 
cxiong 29
xmzhang 28
中國
[root@localhost ~]# cat index.py 
#!/usr/bin/python27
#coding:utf-8


class Person():
    nation='中國'    --- 靜態字段:nation只屬於class,靜態字段只有一份,對象內存中不存在;
    def __init__(self,name,age):
        self.name=name  --- 動態字段:self.name屬於對象
        self.age=age    ---動態字段:self.age屬於對象

p1=Person('cxiong',29)
p2=Person('xmzhang',28)
print p1.name,p1.age
print p2.name,p2.age
print p1.nation
[root@localhost ~]#

注意:類不能訪問動態字段;對象可以訪問靜態字段

靜態字段、動態字段、靜態方法、動態方法和裝飾器

作用:提供統一的方法和數據,用於處理類的請求

[root@localhost ~]# cat index.py 
#!/usr/bin/python27
#coding:utf-8

class Person():
    
    #靜態字段
    nation='中國'

    def __init__(self,name,age):
        #動態字段
        self.name=name
        self.age=age

    #動態方法    
    def Eat(self):
        print self.name+' eating...'

    #靜態方法  --- 不需要實例化類,即可調用方法
    @staticmethod
    def Breath():
        print 'breathing...'
    
    #裝飾器 --- 將方法訪問形式作爲字段形式訪問
    @property
    def Sing(self):
        print self.name+' singing...'

p1=Person('cxiong',29)
p2=Person('xmzhang',28)

print p1.name,p1.age
print p2.name,p2.age
print p1.nation
p1.Eat()
p2.Eat()
Person.Breath()    
p1.Sing


__dict__與dir()的區別

print m1.__dict__   ---類所有字段
{'_Person__gender': 'male', 'age': 29, '_man__gender': 'male', 'name': 'cxiong'}

print dir(m1)   --- 類所有的方法及字段
['Breath', 'Eat', 'ShowGender', 'Sing', '_Person__gender', '__call__', '__class__', '__del__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_man__gender', 'age', 'name', 'nation', 'work']


3、面向對象與函數式編程的區別

靜態方法與模塊形式的區別:內存上沒區別,區別在於,靜態方法邏輯上屬於類;

靜態方法是面嚮對象語言解決對象重複構造方法時產生的,python模塊化語言也可以解決;


多態:將相似的方法包裝在同一個模塊中;

python支持模塊化編程,也支持反射;等同於面向對象編程java、.net


面向對象:可以創建模板



4、私有字段和私有方法

作用:安全

[root@localhost ~]# python index1.py
male
[root@localhost ~]# cat index1.py
#!/usr/bin/python27
#coding:utf-8

class Person():
    
    #靜態字段
    nation='中國'

    def __init__(self,name,age,gender):
        #動態字段
        self.name=name
        self.age=age
        #私有字段
        self.__gender=gender

    #動態方法    
    def Eat(self):
        print self.name+' eating...'

    #靜態方法
    @staticmethod
    def Breath():
        print 'breathing...'
    
    #裝飾器 
    @property
    def Sing(self):
        print self.name+' singing...'

    @property --- 私有字段不能被外部訪問,但是可以使用方法訪問
    def ShowGender(self):
        return self.__gender

p1=Person('cxiong',29,'male')
p2=Person('xmzhang',28,'female')
print p1.ShowGender


只讀私有字段和可改寫私有字段

[root@localhost ~]# cat index1.py
#!/usr/bin/python27
#coding:utf-8

class Person():   --- 沒有繼承object是可讀可寫;繼承了object一個是可讀,一個是可寫
    
    #靜態字段
    nation='中國'

    def __init__(self,name,age,gender):   --- 構造函數
        #動態字段
        self.name=name
        self.age=age
        #私有字段
        self.__gender=gender

    #動態方法    
    def Eat(self):
        print self.name+' eating...'

    #靜態方法
    @staticmethod
    def Breath():
        print 'breathing...'
    
    #裝飾器 
    @property
    def Sing(self):
        print self.name+' singing...'
    
    #只讀私有字段
    @property
    def ShowGender(self):
        return self.__gender

    #可改私有字段
    @ShowGender.setter
    def ShowGender(self,value):
        self.__gender=value


p1=Person('cxiong',29,'male')
p2=Person('xmzhang',28,'female')
print p1.ShowGender
p1.ShowGender='female'
print p1.ShowGender


5、析構函數及__call__方法

[root@localhost ~]# python index1.py
male
female
解釋器要銷燬person了...
解釋器要銷燬person了...
[root@localhost ~]# cat index1.py
#!/usr/bin/python27
#coding:utf-8

class Person(object):
    
    #靜態字段
    nation='中國'

    #構造函數
    def __init__(self,name,age,gender):
        #動態字段
        self.name=name
        self.age=age
        #私有字段
        self.__gender=gender
    
    #析構函數,用於銷燬對象時使用;一般不使用,常用於操作文件
    def __del__(self):
        print '解釋器要銷燬person了...'

    def __call__(self):
        print 'call'

    #動態方法    
    def Eat(self):
        print self.name+' eating...'

    #靜態方法
    @staticmethod
    def Breath():
        print 'breathing...'
    
    #裝飾器 
    @property
    def Sing(self):
        print self.name+' singing...'
    
    #只讀私有字段,property常用於私有字段
    @property
    def ShowGender(self):
        return self.__gender

    #可改私有字段
    @ShowGender.setter
    def ShowGender(self,value):
        self.__gender=value


p1=Person('cxiong',29,'male')
p2=Person('xmzhang',28,'female')
print p1.ShowGender
p1.ShowGender='female'
print p1.ShowGender
p1()  #執行__call__方法

[root@localhost ~]# python index1.py
male
female
call
解釋器要銷燬person了...
解釋器要銷燬person了...


6、繼承

[root@localhost ~]# python index1.py
work hard...
cxiong singing...
breathing...
解釋器要銷燬person了...
[root@localhost ~]# cat index1.py
#!/usr/bin/python27
#coding:utf-8

class Person(object):
    
    #靜態字段
    nation='中國'

    #構造函數
    def __init__(self,name,age,gender):
        #動態字段
        self.name=name
        self.age=age
        #私有字段
        self.__gender=gender
    
    #析構函數
    def __del__(self):
        print '解釋器要銷燬person了...'

    #動態方法    
    def Eat(self):
        print self.name+' eating...'

    #
    def __call__(self):
        print 'call'

    #靜態方法
    @staticmethod
    def Breath():
        print 'breathing...'
    
    #裝飾器 
    @property
    def Sing(self):
        print self.name+' singing...'
    
    #只讀私有字段
    @property
    def ShowGender(self):
        return self.__gender

    #可改私有字段
    @ShowGender.setter
    def ShowGender(self,value):
        self.__gender=value

#man繼承Person類,私有方法__gender無法繼承
class man(Person):

    #重寫__init__方法
    def __init__(self):
        self.name='cxiong'
        self.__gender='male'

    #新增work方法
    def work(self):
        print 'work hard...'

m1=man()
m1.work()
m1.Sing
m1.Breath()




7、新式類與經典類的區別

新式類:繼承object,字段爲只讀和可寫兩種;

經典類:不繼承object,字段均爲讀寫

使用新式類的原因:經典類存在多繼承bug,深度優先,而非廣度優先,請參考以下內容

https://docs.python.org/release/2.2.3/whatsnew/sect-rellinks.html

[root@localhost ~]# cat index1.py
#!/usr/bin/python27
#coding:utf-8

class Person(object):
    
    #靜態字段,Person.nation獲取
    nation='中國'

    #構造函數
    def __init__(self,name,age,gender):
        #動態字段
        self.name=name
        self.age=age
        #私有字段
        self.__gender=gender
        print 'person init...'
    
    #析構函數
    def __del__(self):
        print '解釋器要銷燬person了...'

    #動態方法    
    def Eat(self):
        print self.name+' eating...'

    #
    def __call__(self):
        print 'call'

    #靜態方法
    @staticmethod
    def Breath():
        print 'breathing...'
    
    #裝飾器 
    @property
    def Sing(self):
        print self.name+' singing...'
    
    #只讀私有字段
    @property
    def ShowGender(self):
        return self.__gender

    #可改私有字段
    @ShowGender.setter
    def ShowGender(self,value):
        self.__gender=value

#man繼承Person類    
class man(Person):

    #重寫__init__方法
    def __init__(self):
        self.name='cxiong'
        self.__gender='male'
        print 'man init...'
        #調用父類的init方法1
        Person.__init__(self,'cxiong',29,'male')
        #調用父類的init方法2
        super(man,self).__init__('cxiong',29,'male')

    #新增work方法
    def work(self):
        print 'work hard...'

m1=man()
m1.work()
m1.Sing
m1.Breath()

[root@localhost ~]# python index1.py
man init...
person init...
person init...
work hard...
cxiong singing...
breathing...
解釋器要銷燬person了...
[root@localhost ~]#


8、多繼承

python特有的特性

[root@localhost ~]# python multiple.py
this is D
save method from --A--
[root@localhost ~]# cat multiple.py
#!/usr/bin/python27
#coding:utf-8

class A:
    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):
    def __init__(self):
        print 'this is D'

c=D()
c.save()
[root@localhost ~]# vim multiple.py
[root@localhost ~]# python multiple.py
this is D
save method from --C--
[root@localhost ~]# cat multiple.py
#!/usr/bin/python27
#coding:utf-8

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):
    def __init__(self):
        print 'this is D'

c=D()
c.save()
[root@localhost ~]#



9、接口

規範:抽象類+抽象方法=接口

from abc import ABCMeta, abstractmethod
class Bar:
     __metaclass__ = ABCMeta  
    @abstractmethod    
    def Fun(self):pass
  
class Foo(Bar):    
    def __init__(self):
         print '__init__'
  
Foo()




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章