1. 程式人生 > >面向對象的內功心法

面向對象的內功心法

int eth method 設置 @property 自己的 比較 反射 @class

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

從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
用法沒特別,就是赤裸裸想把這個函數寫入類中,既不是操作對象的屬性,又沒有操作類的方法,所以,什麽都不用傳了!類可以調用,對象也可以調用。

 

面向對象的內功心法