類與物件 cookbook讀書筆記

2021-08-10 03:20:05 字數 4867 閱讀 3923

重新定義它的__str__() 和__repr__() 方法,使用str() 或print() 函式會輸出__str__字串(更適合人閱讀的字串),repr() 函式返回__repr__字串(更適合機器閱讀),__repr__() 生成的文字字串標準做法是需要讓eval(repr(x)) == x 為真。如果實在不能這樣子做,應該建立乙個有用的文字表示,並使用< 和》 括起來。如果__str__() 沒有被定義,那麼就會使用__repr__() 來代替輸出。

為了自定義字串的格式化,我們需要在類上面定義__format__() 方法。

_formats = --',

'mdy' : '//',

'dmy' : '//'

}class date:

def __init__(self, year, month, day):

self.year = year

self.month = month

self.day = day

def __format__(self, code):

if code == '':

code = 'ymd'

fmt = _formats[code]

return fmt.format(d=self)

>>> d = date(2012, 12, 21)

>>> format(d)

'2012-12-21'

>>> format(d, 'mdy')

'12/21/2012'

>>> 'the date is '.format(d)

'the date is 2012-12-21'

>>> 'the date is '.format(d)

'the date is 12/21/2012'

>>>

為了讓乙個物件相容with 語句,你需要實現__enter__() 和__exit__() 方法。編寫上下文管理器的主要原理是你的**會放到with 語句塊中執行。當出現with語句的時候,物件的__enter__() 方法被觸發,它返回的值(如果有的話) 會被賦值給as 宣告的變數。然後,with 語句塊裡面的**開始執行。最後, __exit__() 方法被觸發進行清理工作。

不管with **塊中發生什麼,上面的控制流都會執行完,就算**塊中發生了異常也是一樣的。事實上,__exit__() 方法的第三個引數包含了異常型別、異常值和追溯資訊(如果有的話)。__exit__() 方法能自己決定怎樣利用這個異常資訊,或者忽略它並返回乙個

none 值。如果__exit__() 返回

true ,那麼異常會被清空,就好像什麼都沒發生一樣,with 語句後面的程式繼續在正常執行。

給類新增__slots__屬性來極大的減少例項所佔的記憶體。當你定義__slots__後,python 就會為例項使用一種更加緊湊的內部表示。例項通過乙個很小的固定大小的陣列來構建,而不是為每個例項定義乙個字典,這跟元組或列表很類似。在__slots__中列出的屬性名在內部被對映到這個陣列的指定小標上。使用__slots__乙個不好的地方就是我們不能再給例項新增新的屬性了,只能使用在__slots__中定義的那些屬性名。

python 程式設計師不去依賴語言特性去封裝資料,而是通過遵循一定的屬性和方法命名規約來達到這個效果。第乙個約定是任何以單下劃線開頭的名字都應該是內部實現,使用下劃線開頭的約定同樣適用於模組名和模組級別函式。第二個約定是使用雙下劃線開始會導致訪問名稱變成其他形式,

這種屬性通過繼承是無法被覆蓋的。

class b:

def __init__(self):

self.__private = 0

def __private_method(self):

pass

def public_method(self):

pass

self.__private_method()

類b 中,私有屬性會被分別重新命名為_b__private 和_b__private_method

class c(b):

def __init__(self):

super().__init__()

self.__private = 1 # does not override b.__private

# does not override b.__private_method()

def __private_method(self):

pass

讓你的非公共名稱以單下劃線開頭。但是,如果你清楚你的**會涉及到子類,並且有些內部屬性應該在子類中隱藏起來,那麼才考慮使用雙下劃線方案。

你定義的乙個變數和某個保留關鍵字衝突,這時候可以使用單下劃線作為字尾。

自定義某個屬性的一種簡單方法是將它定義為乙個property

class person:

def __init__(self, first_name):

self.first_name = first_name

# getter function

@property

def first_name(self):

return self._first_name

# setter function

@first_name.setter

def first_name(self, value):

if not isinstance(value, str):

raise typeerror('expected a string')

self._first_name = value

# deleter function (optional)

@first_name.deleter

def first_name(self):

raise attributeerror("can't delete attribute")

property 的乙個關鍵特徵是它看上去跟普通的attribute 沒什麼兩樣,但是訪問它的時候會自動觸發getter 、setter 和deleter 方法。

如果你想建立乙個全新的例項屬性,可以通過乙個描述器類的形式來定義它的功能。乙個描述器就是乙個實現了三個核心的屬性訪問操作(get, set, delete) 的類,分別為__get__() 、__set__() 和__delete__() 這三個特殊的方法。這些方法接受乙個例項作為輸入,之後相應的操作例項底層的字典。

class integer:

def __init__(self, name):

self.name = name

def __get__(self, instance, cls):

if instance is none:

return self

else:

return instance.__dict__[self.name]

def __set__(self, instance, value):

if not isinstance(value, int):

raise typeerror('expected an int')

instance.__dict__[self.name] = value

def __delete__(self, instance):

del instance.__dict__[self.name]

class point:

x = integer('x')

y = integer('y')

def __init__(self, x, y):

self.x = x

self.y = y

當你這樣做後,所有隊描述器屬性(比如x 或y) 的訪問會被__get__() 、__set__()和__delete__() 方法捕獲到。

描述器可實現大部分python 類特性中的底層魔法, 包括@classmethod 、@staticmethod 、@property ,甚至是__slots__特性。描述器的乙個比較困惑的地方是它只能在類級別被定義,而不能為每個例項單獨定義。

如果你只是想簡單的自定義某個類的單個屬性訪問的話就不用去寫描述器了,這種情況下使用property 技術會更加容易,當程式中有很多重複**的時候描述器就很有用了。

如果乙個描述器僅僅只定義了乙個__get__() 方法的話,它比通常的具有更弱的繫結。特別地,只有當被訪問屬性不在例項底層的字典中時__get__() 方法才會被觸發。

為了呼叫父類(超類) 的乙個方法,可以使用super() 函式

為了實現多個構造器,你需要使用到類方法。

import time

class date:

""" 方法一:使用類方法"""

# primary constructor

def __init__(self, year, month, day):

self.year = year

self.month = month

self.day = day

# alternate constructor

@classmethod

def today(cls):

t = time.localtime()

return cls(t.tm_year, t.tm_mon, t.tm_mday)

a = date(2012, 12, 21) # primary

b = date.today() # alternate

裝飾器functools.total_ordering(類裝飾器) ,你只需定義乙個__eq__() 方法,外加其他方法( __lt__, __le__, __gt__, __ge__ ) 中的乙個即可。然後裝飾器會自動為你填充其它比較方法。

類與物件 物件

一 什麼是物件?1.物件是由我們自己建立的類來建立出來的。2.物件就是類的例項 可以真正使用類的資料,可以呼叫類中元素的資料 3.乙個類可以建立出多個物件 二 如何建立物件?1.保證用來建立物件的類是存在 2.需要通過類中提供的構造方法建立物件 格式 new 構造方法 引數值 三 建立好的物件的有何...

類與物件(類 物件 物件的比較)

類 是對某一事物的抽象描述,通過方法 成員方法 和屬性 成員變數 來描述事物。物件 物件 是實際存在的該類事物的個體,因而也稱例項。1 類與物件 建立圓類 1 package circle 23 public class circle 9public double getradius 1213 pu...

OC物件導向思想,類和物件的關係,類的設計筆記

一,物件導向和面向過程思想 oc是物件導向的,c語言是面向過程的,兩種都是解決問題的思想 面向過程 proceduce oriented 找步驟 物件導向 object oriented 找物件 物件導向程式設計 object oriented programming 簡稱oop 二,類和物件的關係...