首頁 >後端開發 >Python教學 >python魔法方法-屬性轉換和類別的表示詳解

python魔法方法-屬性轉換和類別的表示詳解

WBOY
WBOY原創
2016-08-04 08:55:371250瀏覽

型轉換魔法

型轉換魔法其實就是實現了str、int等工廠函數的結果,通常這些函數還有型別轉換的功能,以下是一些相關的魔法方法:

•__int__(self)

•轉換成整數型,對應int函數。

•__long__(self)

•轉換成長整型,對應long函數。

•__float__(self)

•轉換成浮點型,對應float函數。

•__complex__(self)

•轉換成 複數型,對應complex函數。

•__oct__(self)

•轉換成八進制,對應oct函數。

•__hex__(self)

•轉換成十六進制,對應hex函數。

•__index__(self)

•首先,這個方法應該回傳一個整數,可以是int或long。這個方法在兩個地方有效,首先是 operator 模組中的index函數得到的值就是這個方法的回傳值,其次是用來切片操作,下面會特別進行程式碼示範。

•__trunc__(self)

•當 math.trunc(self) 使用時被調用.__trunc__返回自身類型的整數截取 (通常是一個長整型).

•__coerce__(self, other)

•實現了類型的強制轉換,這個方法對應於coerce 內建函數的結果(python3.0開始去掉了此函數,也就是該魔法方法也沒意義了,至於後續的版本是否重新加入支持,要視官方而定。

•這個函數的作用是強制性地將兩個不同的數字類型轉換成為同一個類型,例如:

方法傳回一個元祖,分別對應轉換後的兩個數字。其優先權為:複數>浮點數>長整數>整數。在轉換的時候,會轉換為兩個參數中優先順序高的型別。當轉換無法完成的時候,會觸發 TypeError。

而當我們定義這個魔法方法時,如果轉換無法完成,應該返回None。

這裡有個重要的機制,當python進行運算的時候,如1 + 1.0 時,會先呼叫coerce 函數將其轉換為同一個類型,然後再進行運行,這也就是為什麼1 + 1.0 = 2.0,因為轉換之後實際進行的運算為1.0 +1.0。得到這樣的結果也就不奇怪了。

程式碼範例:

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __int__(self):
    return int(self.x) + 1

  def __long__(self):
    return long(self.x) + 1

a = Foo(123)
print int(a)
print long(a)
print type(int(a))
print type(long(a))

這裡要注意一點,魔法方法的回傳值必須符合預期,例如__int__ 就應該回傳一個

 int 類型,如果我們任性地回傳其他類型,例如字串(str)、列表(list)等,會報錯。

def __int__(self):
    return str(self.x)

def __int__(self):
    return list(self.x)

但是 int 可以回傳 long,而 long 回傳 int 時會自動被處理成 long:

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __int__(self):
    return long(self.x) + 1

  def __long__(self):
    return int(self.x) + 1

a = Foo(123)
print int(a)
print long(a)
print type(int(a))
print type(long(a))

以上發生在python2.7.11上,這是一個很奇怪的行為,以至於我認為其可能是一個 BUG,總之我們在使用的時候要注意要返回對應的類型就是了,以免出​​錯。


__index__(self):

首先是對應於operator.index(),operator.index(a)就相當於a.__index__():

import operator

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __index__(self):
    return self.x + 1

a = Foo(10)
print operator.index(a)

另一個是很神奇的特效,當其用於序列中:

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __index__(self):
    return 3

a = Foo('scolia')
b = [1, 2, 3, 4, 5]
print b[a]
print b[3]

可以當作索引一樣使用,可進行切片操作:

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __index__(self):
    return int(self.x)

a = Foo('1')
b = Foo('3')
c = [1, 2, 3, 4, 5]
print c[a:b]
 

其實切片內部使用的函數 slice 對其進行了處理,有興趣的同學可以去了解這個函數:

a = Foo('1')
b = Foo('3')
c = slice(a, b)
print c
d = [1, 2, 3, 4, 5]
print d[c]

 __coerce__(self, other):

程式碼範例:

class Foo(object):
  def __init__(self, x):
    self.x = x

  def __coerce__(self, other):
    return self.x, str(other.x)

class Boo(object):
  def __init__(self, x):
    self.x = x

  def __coerce__(self, other):
    return self.x, int(other.x)

a = Foo('123')
b = Boo(123)
print coerce(a, b)
print coerce(b, a)

 總結:是呼叫了第一個參數的魔法方法。

類的表示 :

類別的表示其實就是對外的特徵,例如使用print語句時,印出來的是什麼,其實本質上也是對應函數的輸出:

•__str__(self)

•定義當 str() 被你的一個類別的實例呼叫時所要產生的行為。因為print預設呼叫的就是str()函數。

•__repr__(self)

•定義當 repr()  被你的一個類別的實例呼叫時所要產生的行為。 str() 和 repr() 的主要差異在於其目標群體。 repr() 回傳的是機器可讀的輸出,而 str() 回傳的是人類可讀的。  repr() 函數是交換模式預設呼叫的

•函數。

•__unicode__(self)

•定義當 unicode() 被你的一個類別的實例呼叫時所要產生的行為。 unicode() 和 str() 很相似,但是回傳的是unicode字串。注意,如果對你的類別呼叫 str() 然而你只定義了 __unicode__() ,那麼其將不會

•工作。你應該定義 __str__() 來確保呼叫時能回傳正確的值,並不是每個人都有心情去使用unicode()。

•__format__(self, formatstr)

•定義當你的一個類別的實例被用來用新式的格式化字串方法進行格式化時所要產生的行為。例如, "Hello, {0:abc}!".format(a) 將會導致呼叫 a.__format__("abc") 。這對定義你自己的數值或字串類型

•是十分有意義的,你可能會給出一些特殊的格式化選項。

•__hash__(self)

•定義當 hash()被你的一個類別的實例呼叫時所要產生的行為。它必須傳回一個整數,用來在字典中進行快速比較。

•請注意,實現__hash__時通常也要實作__eq__。有下面這樣的規則:a == b 暗示著 hash(a) == hash(b) 。也就是說兩個魔法方法的回傳值最好一致。

•這裡引入一個‘可哈希物件'的概念,首先一個可哈希物件的哈希值在其生命週期內應該是不變的,而要得到哈希值就意味著要實現__hash__方法。而雜湊物件之間是可以比較的,這意味著要實作__eq__或

•者__cmp__方法,而雜湊物件相等必須其雜湊值相等,要實現這個特性就意味著__eq__的回傳值必須和__hash__一樣。

•可雜湊物件可以作為字典的鍵和集合的成員,因為這些資料結構內部使用的就是雜湊值。 python中所有內建的不變的物件都是可哈希的,例如元組、字串、數字等;而可變物件則不能哈希,例如列表、

•字典等。

•使用者定義的類別的實例預設是可雜湊的,並且除了它們本身以外誰也不相等,因為其雜湊值來自於 id 函數。但這並不代表 hash(a) == id(a),要注意這個特性。

•__nonzero__(self)

•定義當 bool() 被你的一個類別的實例呼叫時所要產生的行為。本方法應該回傳True或False,取決於你想讓它傳回的值。 (python3.x中改為__bool__)

•__dir__(self)

•定義當 dir() 被你的一個類別的實例呼叫時所要產生的行為。該方法應該傳回一個屬性的清單給使用者。

•__sizeof__(self)

•定義當 sys.getsizeof() 被你的一個類別的實例呼叫時所要產生的行為。這個方法應該以位元組為單位,回傳你的物件的大小。這通常對於以C擴展的形式實現的Python類別更加有意義,其有助於理解這些擴展。

這裡並沒有什麼特別難懂的地方,所以程式碼範例就略去了。

以上這篇python魔法方法-屬性轉換和類別的表示詳解就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn