1. 程式人生 > 程式設計 >Python中的特殊方法以及應用詳解

Python中的特殊方法以及應用詳解

前言

Python 中的特殊方法主要是為了被直譯器呼叫的,因此應該儘量使用 len(my_object) 而不是 my_object.__len__() 這種寫法。在執行 len(my_object) 時,Python 直譯器會自行呼叫 my_object 中實現的 __len__ 方法。

除非有大量的超程式設計存在,直接呼叫特殊方法的頻率應遠小於實現它們的次數。

模擬數值型別

可以通過在自定義物件中實現 __add__ 和 __mul__ 等特殊方法 ,令其支援 +、* 等運算子。

如下面的模擬向量的 Vector 類:

# vector.py
from math import hypot

class Vector:
  def __init__(self,x=0,y=0):
    self.x = x
    self.y = y

  def __repr__(self):
    return f'Vector({self.x},{self.y})'

  def __abs__(self):
    return hypot(self.x,self.y)

  def __bool__(self):
    return bool(self.x or self.y)

  def __add__(self,other):
    return Vector(self.x + other.x,self.y + other.y)

  def __mul__(self,scalar):
    return Vector(self.x * scalar,self.y * scalar)

執行效果如下:

>>> from vector import Vector
>>> v1 = Vector(2,4)
>>> v2 = Vector(2,1)
>>> v1 + v2
Vector(4,5)
>>> v = Vector(3,4)
>>> abs(v)
5.0
>>> v * 3
Vector(9,12)

物件的字串表示

Python 有一個 repr 內建函式,能把一個物件用字串的形式表示出來。實際上這種字串表達是通過物件內部的 __repr__ 特殊方法定義的。預設情況下,在控制檯裡檢視某個物件時,輸出的字串一般是 <xxx object at 0x7fc99d6ab2e0> 這種形式。

__repr__ 返回的字串應該準確、無歧義,並儘可能表示出該物件是如何建立的。比如前面的 Vector 物件,其 __repr__ 中定義的字串形式類似於 Vector(3,4),和物件初始化的語法非常近似。

__repr__ 和 __str__ 的區別在於,__str__ 是在向物件應用 str() 函式(或者用 print 函式列印某個物件)時被呼叫。其返回的字串對終端使用者更友好。

如果只想實現其中一個特殊方法,__repr__ 應該是更優的選擇。在物件沒有實現 __str__ 方法的情況下,Python 直譯器會用 __repr__ 代替。

# myclass.py
class MyClass:
  def __repr__(self):
    return 'MyClass'

  def __str__(self):
    return 'This is an instance of MyClass'

>>> from myclass import MyClass
>>> my = MyClass()
>>> my
MyClass
>>> print(my)
This is an instance of MyClass

自定義布林值

Python 裡有 bool 型別,但實際上任何物件都可以用在需要 bool 型別的上下文(比如 if 或 while 語句)中。為了判斷某個值 x 的真假,Python 會呼叫 bool(x) 返回 True 或 False。

預設情況下,自定義類的例項總是為真。除非這個類對於 __bool__ 或 __len__ 方法有自己的實現。
bool(x) 實際上呼叫了物件 x 中的 __bool__ 方法。如不存在 __bool__ 方法,則 bool(x) 會嘗試呼叫 x.__len__(),返回 0 則為 False,否則為 True。

# boolclass.py
class BoolClass:
  def __init__(self):
    self.list = []

  def add(self,item):
    self.list.append(item)

  def __len__(self):
    return len(self.list)

>>> from boolclass import BoolClass
>>> b = BoolClass()
>>> len(b)
0
>>> bool(b)
False
>>> b.add(1)
>>> len(b)
1
>>> bool(b)
True
# boolclass.py
class BoolClass:
  def __init__(self):
    self.list = []

  def add(self,item):
    self.list.append(item)

  def __len__(self):
    return len(self.list)

  def __bool__(self):
    return bool(sum(self.list))

>>> from boolclass import BoolClass
>>> b = BoolClass()
>>> b.add(1)
>>> len(b)
1
>>> bool(b)
True
>>> b.add(-1)
>>> len(b)
2
>>> bool(b)
False

參考資料

Fluent Python

總結

到此這篇關於Python中特殊方法以及應用詳解的文章就介紹到這了,更多相關Python特殊方法及應用內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!