在python中以雙下劃線開頭,雙下劃線結(jié)尾的內(nèi)置函數(shù)
使用魔法函數(shù)可以增強(qiáng)對象的類型 例如:
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __getitem__(self, item):
return self.employee[item]
#實(shí)現(xiàn)了這個魔法函數(shù),就實(shí)現(xiàn)了迭代類型,可迭代類型的作用就是可以直接使用for循環(huán)去調(diào)用
company = Company(['tom', 'alice','jim'])
company1 = company[ :2]
for em in company1:
print(em)

這樣就會增強(qiáng)對象的類型,使對象可迭代,可序列化
常見的特殊方法
1、重寫repr方法
object 類提供的repr()方法總是返回該對象實(shí)現(xiàn)類的“類名+object at+ 內(nèi)存地址”值,這個返回值并不能真正實(shí)現(xiàn)“自我描述”的功能,因此如果用戶需要自定義類能實(shí)現(xiàn)“自我描述”的功能,就必須重寫repr()方法。
class Computer:
def __init__(self, name, price):
self.name = name
self.price = price
im = Computer('鼠標(biāo)', 29.8)
print(im)
print() 函數(shù) 只能在控制臺打印字符串,而computer實(shí)際是一個內(nèi)存中的對象,使用該方法輸出的Computer對象實(shí)際上輸出的是Coputer對象的repr()方法的返回值。
<__main__.Computer object at 0x000000000110E4E0>
repr()是python類中一個特殊的方法,由于object類已提供了該方法,而所有的python類都繼承于object,因此所有的python對象都具有repr()方法
class Apple:
#實(shí)現(xiàn)構(gòu)造器:
def __init__(self, color, weight):
self.color = color
self.weight = weight
#重寫__repr_()方法
def __repr__(self):
return "Apple[color= " + self.color+",weight = " + str(self.weight) + "]"
a = Apple("紅色", 5)
print(a)
輸出
Apple[color= 紅色,weight = 5]
2、del()析構(gòu)函數(shù),用于垃圾回收,在后邊的文章中有詳細(xì)介紹
3、dir()方法
對象的dir()方法用于列出該對象內(nèi)部所有的屬性(包括方法)名,該方法將會返回包含所有屬性(方法)名的序列。
當(dāng)程序?qū)δ硞€對象執(zhí)行dir(object)函數(shù)時,實(shí)際上就是將該對象的dir()方法返回值進(jìn)行排序,然后包裝成列表。

4、dict屬性
dict屬性用于查看對象內(nèi)部存儲的所有屬性名和屬性值組成的字典,通常程序直接使用該屬性即可。程序使用dict屬性既可以查看對象的所有內(nèi)部狀態(tài),也可以通過字典的語來訪問或修改指定屬性的值。
class Item:
def __init__(self, name, price):
self.name = name
self.price = price
im = Item('鼠標(biāo)', 100)
print(im.__dict__)
#通過__dict__來訪問name 和 price 屬性
print(im.__dict__['name'])
print(im.__dict__['price'])
im.__dict__['name'] = '鍵盤'
im.__dict__['price'] = 200
print(im.name)
輸出
{'name': '鼠標(biāo)', 'price': 100}
鼠標(biāo)
100
鍵盤
5、getattr 和 setattr等
當(dāng)程序操作(包括訪問、設(shè)置、刪除)對象的屬性時,python系統(tǒng)會同樣執(zhí)行該對象特定的方法。
__getattribute__(self, name) 當(dāng)程序訪問對象的name屬性時會被自動調(diào)用
__getattr__(self, name) 當(dāng)程序訪問對象的name屬性且該屬性不存在時被自動調(diào)用。
__setattr__(self, name, value) 當(dāng)程序?qū)ο蟮膎ame屬性賦值時被自動調(diào)用
__delattr__(self, name) 當(dāng)程序刪除對象的name屬性時被自動調(diào)用
當(dāng)python類的屬性不存在時,通過重寫上邊的方法可以合成新屬性
class Rectange(object):
"""docstring for Rectange"""
def __init__(self, width, height):
self.width = width
self.height = height
def __setattr__(self, name, value):
print('----設(shè)置%s屬性-----' %name)
if name == "size":
self.width, self.height = value
else:
self.__dict__[name] = value
def __getattr__(self, name):
print('------讀取%s屬性-----' %name)
if name == 'size':
return self.width, self.height
else:
raise AattributeError
def __delattr__(self, name):
print('----刪除%s屬性----' %name)
if name == 'size':
self.__dict__['width'] = 0
self.__dict__['height'] = 0
當(dāng)size屬性不存在時,會調(diào)用getattr()方法
rect = Rectange(3, 4)
print(rect.size)
輸出
----設(shè)置width屬性-----
----設(shè)置height屬性-----
------讀取size屬性-----
(3, 4)
當(dāng)訪問的屬性存在時,不會調(diào)用getattr()方法
rect.size = 6, 8
print(rect.width)
輸出
----設(shè)置size屬性-----
----設(shè)置width屬性-----
----設(shè)置height屬性-----
6
如果程序在讀取,設(shè)置屬性之前要進(jìn)行某種攔截處理(比如檢查數(shù)據(jù)是否合法之類的),也可以通過重寫setattr()或getattribute方法來實(shí)現(xiàn)。
class User(object):
"""docstring for User"""
def __init__(self, name, age):
self.name = name
self.age = age
#重寫__setattr__()方法對設(shè)置的屬性進(jìn)行檢查
def __setattr__(self, name, value):
#如果正在設(shè)置name屬性
if name == 'name':
if 2<len(value)<= 8 or len(value) >8 :
self.__dict__['name'] = value
else:
raise ValueError('name的長度必須在2-8之間')
elif name == 'age':
if 10 < value < 60:
self.__dict__['age'] = value
else:
raise ValueError('age值必須在10-60之間')
u = User('bobo', 20)
print(u.name)
print(u.age)
u.name = 'c'
6、與序列相關(guān)
序列最重要的特征就是可以包含多個元素
__len__(self) 返回值決定序列中元素個數(shù)
__getitem__(self, key) 該方法獲取指定索引對象的元素。key應(yīng)該是整數(shù)值或者slice對象,否則會引發(fā)KeyError異常
__contains__(self, item) :該方法可以判斷序列是否包含指定元素 if in 的內(nèi)部實(shí)現(xiàn)機(jī)制就是通過該魔術(shù)方法
__setitem__(self, key, value) 該方法設(shè)置指定索引對應(yīng)的元素。key應(yīng)該是整數(shù)值或者slice對象,否則會引發(fā)KeyError異常
__delitem__(self, key): 該方法刪除指定索引對應(yīng)的元素
如果程序要實(shí)現(xiàn)不可變序列,只要實(shí)現(xiàn)上面三個方法即可,如果要實(shí)現(xiàn)可變序列,則需要實(shí)現(xiàn)上面的5個方法