1. 程式人生 > >面向物件的內功心法

面向物件的內功心法

這裡分為兩個部分,內建方法和內建函式。當然,內建方法是特別的多的,這裡只是冰山一角,但一定都是最最能用的到的。這的內建函式也會講解一些特殊用法,都是減少程式碼的,提升程式碼質量。

從python深處說,應該先聊聊內建方法:

__new__(cls,*args,**kwd)  構造方法, 可以開闢處一塊記憶體空間
__init__(self)        初始化物件,建立物件的時候,可以存一些物件初始的屬性,
                 在例項化的時候,就會自動的執行。
**這裡解釋一下類的執行過程:
  在定義類的時候,就會開闢處一個空間,這個空間是給這個類的,在這個名稱空間中,有靜態屬性,動態屬性
  類方法@classmethod,靜態方法@staticmethod,偽裝屬性方法@property,雙下方法,當然__init__方法,
  重點就在這個__init__上,在例項化一個物件的時候,首先執行一個__new__,開創一個空間,因為這時,在有
  物件之前,所以不用self,而是cls。然後在__init__中,以字典的形式,新增一些屬性。這時,把這片空間的內
  存地址給到self,這時,在把self的地址通過例項化後,就賦值給了物件。當然,在這片空間中,還有一個類指標,
  會把這片空間指向了類名稱空間。在呼叫屬性或方法時,先從自己的空間裡找,如果找不到,就去類的空間裡找。再
  找不到,就報錯。
__call__(self,*args)     把物件作為函式呼叫時候執行,物件加括號,就會自動呼叫
                 類中__call__方法下的程式碼。
__str__             print(obj)\str(obj)\"%s"%obj 都會觸發__str__
__repr__ repr(obj)\"%r"%obj  都會觸發__repr__,這個方法也是__str__的備胎
__del__(self)     析構方法 釋放物件,在物件被刪除之前呼叫
__eq__(self,other)      判斷self物件的屬性是否等於other物件的屬性
                 a.name==b.name
                 def __eq___(self,other):
                    if self.name ==other.name:
                      return True
                    return Flase
__hash__            hash(obj) 會觸發
__getattr__          獲取屬性的值。
__setattr__          設定屬性的值。修改或增加都會觸發。
__delattr__          刪除name的屬性。刪除會觸發
__getattribute__       功能和getattr相似,但是效果比較好一些。
以上都時和使用名稱空間加點的取值方式有關的。
值得注意的是,getattr如果取的是存在的屬性,會取出其中的值,但是,如果是不存在的屬性,就會呼叫getattr方法
第二點要注意的是,很多人會在呼叫方法的時候,陷入遞迴鎖的陷阱,應該用self._dict_[]的方式來完成。

 最有用的自省--------反射

hasattr()是否存在
getattr()獲取屬性的值,或者是方法的地址
setattr()建立或修改值的時候
delattr()刪除屬性
類\物件\模組\實際上都有自己的名稱空間,實際上,反射都是一個邏輯 值=getattr(名稱空間,字串) 如果字串是屬性,那麼值就是屬性,如果字串是
方法,結果就是函式的記憶體地址。
小重點:類的名稱空間:靜態方法,類方法,靜態方法,普通方法,property方法。這些都是可以變成私有的。
    物件的名稱空間:物件的屬性
如何呼叫本檔案中的變數名?
from sys import modules:
  ret = getattr(modules[__name__],string)

 

 

 

 

有些好玩的裝飾器

偽裝成屬性的方法
@property
class Person:
def __init__(self,name):
self.__name = name # 不讓外面隨便修改

@property #將這個方法變成一個屬性。簡單的說,就是不用再用 物件.方法() 這樣的形式來呼叫了。就是用 (物件|類名).方法 連括號都不用加了
def name(self):
return self.__name

alex = Person('孫悟空')
print(alex.name)

小升級的地方
修改偽裝成屬性的方法
class Person:
def __init__(self,name):
self.__name = name # 不讓外面隨便修改 可以寫一個介面,讓外面來呼叫

@property
def name(self):
return self.__name

@name.setter # 之前必須有一個同名的方法被property裝飾過,這裡的name必須是前面的name是相互呼應的
def name(self,new_name): #之前必須有一個同名的方法被property裝飾過,這裡的name必須是前面的name是相互呼應的
if type(new_name) is str:
self.__name = new_name

@name.deleter #之前必須有一個同名的方法被property裝飾過,這裡的name必須是前面的name是相互呼應的
def name(self): #之前必須有一個同名的方法被property裝飾過,這裡的name必須是前面的name是相互呼應的
del self.__name

def set_name(self,new_name):
if type(new_name) is str:
self.__name = new_name
孫悟空 = Person('孫悟空')
print(孫悟空.name)
孫悟空.set_name(“豬八戒”)
print(孫悟空.name)
#相當於 孫悟空.name = '豬八戒'
print(孫悟空.name)
del 孫悟空.name # 只是相當於呼叫被deleter裝飾的方法,並不相當於刪除name屬性
print(孫悟空.name)

  

剩下兩個就是
類方法的裝飾器
@classmethod
用法沒有特別,就是不用物件來呼叫了,可以用類來呼叫,差別就在於傳入的引數不是self了而是cls 不過,還是可以用物件來呼叫的,類當然也可以
靜態方法
@staticmethod
用法沒特別,就是赤裸裸想把這個函式寫入類中,既不是操作物件的屬性,又沒有操作類的方法,所以,什麼都不用傳了!類可以呼叫,物件也可以呼叫。