1、對象的屬性?
????python一切皆對象,每個對象都可能有多個屬性。python的屬性有一套統一的管理方案。?
屬性的__dict__系統?
????對象的屬性可能來自于其類定義,叫做類屬性;還可能是該對象實例自身定義的屬性,叫做對象屬性。類屬性可能來自類定義自身,也可能根據定義繼承而來。?
????對象的屬性存儲在對象的__dict__屬性中,__dict__是一個詞典,鍵為屬性名,值為屬性本身。例如:
class Bird(object):feather = Trueclass Chicken(Bird):fly = Falsedef __init__(self, age):self.age = agesummer = chicken(2)
print Bird.__dict__
print Chicken.__dict__
print summer.__dict__{'__dict__': <attribute '__dict__' of 'Bird' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Bird' objects>, 'feather': True, '__doc__': None}{'fly': False, '__module__': '__main__', '__doc__': None, '__init__': <function __init__ at 0x2b91db476d70>}{'age': 2}
????可以看出,對類或對象(實際類也是一類對象)調用__dict__方法,只是返回該類或對象新增的屬性。如果只有一個對象,而不知道它的類以及其他信息的時候,可以利用__class__屬性找到對象的類,然后調用類的__base__屬性來查詢父類。?
????可以通過__dict__來獲取和設置對象的屬性。
summer.__dict__['age'] = 3
print(summer.__dict__['age'])summer.age = 5
print(summer.age)
使用特殊方法__getattr__?
????可以使用 __getattr__(self, name) 來查詢即時生成的屬性,當我們查詢一個屬性的時候,如果通過__dict__方法無法找到該屬性,那么python會調用該對象的__getattr__方法。
class bird(object):feather = Trueclass chicken(bird):fly = Falsedef __init__(self, age):self.age = agedef __getattr__(self, name):if name == 'adult':if self.age > 1.0: return Trueelse: return Falseelse: raise AttributeError(name)summer = chicken(2)
print(summer.adult)
summer.age = 0.5 #本身有age屬性
print(summer.adult) #本省沒有age屬性,會調用__getattr__方法
print(summer.male) #本省沒有age屬性,會調用__getattr__方法,拋出異常每個特性需要有自己的處理函數,而__getattr__可以將所有的即時生成屬性放在同一個函數中處理。__getattr__可以根據函數名區別處理不同的屬性。
比如上面我們查詢屬性名male的時候,raise AttributeError。
?
python中還有一個__getattribute__特殊方法,用于查詢任意屬性,而__getattr__只能用來查詢不在__dict__系統中的屬性。
2、閉包?
函數對象作用域?
????python中函數也是對象,函數對象也有其存活的范圍,就是函數對象的作用域。函數對象用def語句定義,函數對象的作用域與def所在的層級相同。比如,在函數A中定義內部函數B,內部函數B只能在定義該函數A內部使用,不能在函數A外部使用。
def line_conf():def line(x):return 2*x+1print(line(5)) # within the scopeline_conf()
print(line(5)) # out of the scope
如果使用lambda定義函數,那么函數對象的作用域與lambda所在的層級相同。
閉包?
????函數是一個對象,所以可以作為某個函數的返回結果。
def line_conf():b = 15def line(x):return 2*x+breturn line # return a function objectb = 5
my_line = line_conf()
print(my_line(5))
?
line定義的隸屬程序塊中引用了高層級的變量b,但b信息存在于line的定義之外,成b為line的環境變量。line作為line_conf的返回值時,line中已經包含了b的取值(盡管b并不隸屬于line).?
????一個函數和它的環境變量合在一起就構成了一個閉包。在python中,閉包就是一個包含有環境變量取值的函數對象,環境變量取值被保存在函數對象的__closure__屬性中。比如:
def line_conf():b = 15def line(x):return 2*x+breturn line # return a function objectb = 5
my_line = line_conf()
print(my_line.__closure__)
print(my_line.__closure__[0].cell_contents)
?
__closure__里包含了一個元組,該元組中的每個元素都是cell類型的對象。
def line_conf(a, b):def line(x):return ax + breturn lineline1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5), line2(5))
只需要變換參數a,b,就可以獲得不同的直線表達函數。由此,我們可以看到,
閉包也具有提高代碼可復用性的作用。
?
3、裝飾器?
????裝飾器是一種高級的python語法,裝飾器可以對一個函數、方法或者類進行加工。?
(1)裝飾函數和方法?
????裝飾器經常用于對一些函數添加這些函數需要共同執行的一些操作。
#定義裝飾器函數,裝飾器名任意
def decorator(F):def new_F(a, b):print("input", a, b)return F(a, b)return new_F #返回一個可調用對象,該可調用對象以函數為參數# get square sum
@decorator #使用裝飾器進行裝飾,在前面使用 @裝飾器名
def square_sum(a, b):return a**2 + b**2# get square diff
@decorator
def square_diff(a, b):return a**2 - b**2print(square_sum(3, 4))
print(square_diff(3, 4))
#使用裝飾器的效果等同于,將函數重定義
square_sum = decorator(square_sum)
square_sum(3, 4)
?
(2)含參的裝飾器?
????裝飾器允許我們在調用裝飾器的時候提供其他參數,比如 @decorator(params..)
#a new wrapper layer
def pre_str(pre=''):#old decoratordef decorator(F):def newF(a, b):print (pre + 'intput', a, b)return F(a,b)return newFreturn decorator@pre_str('xxxfjdflsd') #提供裝飾器參數
def square_num(a, b):return a**2 + b**2
?
(3)裝飾類?
????一個裝飾器可以接收一個類,并返回一個類,達到加工類的效果。
def decorator(aClass):class newClass(object):def __init__(self, age):self.total_display = 0self.wrapped = aClass(age)def display(self):self.total_display += 1print('total display', self.total_display)self.wrapped.display()return newClass@decorator
class Bird(object):def __init__(self, age):self.age = agedef display(self):print('my age is', self.age)eagleLord = Bird(5)for i in range(3):eagleLord.dislay()
?
參考:
http://www.cnblogs.com/vamei/archive/2012/09/13/2682778.html
總結
以上是生活随笔為你收集整理的python语法笔记(四)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。