Python基礎11(魔法方法)

OohMuYi發表於2020-12-16

1基本的魔術方法

1.1__init__

  • 語法:__init__(self[, ...])
  • 作用:
    • 1 會在呼叫類時自動觸發執行,用來為物件初始化自己獨有的資料
    • 2 __init__內應該存放的是為物件初始化屬性的功能,但是也可以存放其他程式碼,想要在類呼叫時就立刻執行
    • 3 __init方法必須返回物件
  • 解釋:當物件呼叫類時,__init__(self[, ...])會自動被觸發,Python會自動將當前呼叫的空物件傳給self引數。
  • 過程:
    • 1 先產生一個空物件,呼叫類內的__new__方法
    • 2 python會自動呼叫類中的__init__方法,然後將空物件和已經呼叫類時括號裡傳入的引數,一同傳給__init__
    • 3 返回初始化好的物件
  • 注意:__init__(self[, ...])不能返回什麼值,返回的是None。
class Rec:
    def __init__(self,x,y):
        self.x=x
        self.y=y
    def getPeri(self):
        return (self.x+self.y)*2
    def getArea(self):
        return self.x*self.y
rect=Rec(3,4) # 將rect這個物件傳給self
print(rect.getPeri()) # 14
print(rect.getArea())	# 12

1.2__new__

  • 語法:__new__(cls[, ...])
    • __new__至少要有一個引數cls,代表要例項化的類,此引數在例項化時由 Python 直譯器自動提供,後面的引數直接傳遞給__init__
  • 過程:
    • __new__對當前類進行了例項化,並將例項返回,傳給__init__self
    • 但是,執行了__new__,並不一定會進入__init__,只有__new__返回了值,當前類cls的例項,當前類的__init__才會進入。
  • 作用:構造方法。__new__是在一個物件例項化的時候所呼叫的第一個方法,在呼叫__init__初始化前,先呼叫__new__
class A:
    # 構造方法,建立一塊物件的空間,有一個指標能指向類--》__new__
    def __new__(cls, *args, **kwargs): 
        o=super().__new__(cls)
        print('執行new',o)
        return o
    def __init__(self):
        print('執行init',self)
A()
# 執行new <__main__.A object at 0x000001C29AD65F40>
# 執行init <__main__.A object at 0x000001C29AD65F40>

1.3__str__和__repr__

1__str__

  • 當你列印一個物件的時候,觸發__str__
  • 當你使用%s格式化的時候,觸發__str__
  • str強轉資料型別的時候,觸發__str__

2__repr__

  • reprstr的備胎
  • __str__的時候執行__str__,沒有實現__str__的時候,執行__repr__
  • repr(obj)內建函式對應的結果是__repr__的返回值
  • 當你使用%r格式化的時候 觸發__repr__
class p:
    def __init__(self):
        self.student=[]
    def append(self,name):
        self.student.append(name)

py22=p()
print(py22)	# <__main__.p object at 0x00000252BC1A49D0>
py22.append('jaja')
print(py22)	# <__main__.p object at 0x00000252BC1A49D0>
-------------------------------------
class p:
    def __init__(self):
        self.student=[]
    def append(self,name):
        self.student.append(name)
    def __str__(self):
        return str(self.student)

py22=p()
print(py22)	# []
py22.append('jaja')
print(py22)	# ['jaja']

1.4__del__

  • 作用:析構器,當一個物件將要被系統回收時呼叫的方法
class C(object):
    def __init__(self):
        print('into C __init__')

    def __del__(self):
        print('into C __del__')
c1 = C()
# into C __init__
c2 = c1
c3 = c2
del c3
del c2
del c1
# into C __del__

2 魔法運算:算數運算

2.1__add__和__sub__

  • __add__(self,other):定義加法的行為
  • __add__(self,other):定義減法的行為
class A(int):
    def __add__(self, other):
        return int.__add__(self,other)
    def __sub__(self, other):
        return int.__sub__(self, other)
a=A(2)
b=A(3)
print(a+b)	# 5
print(a-b)	# -1

2.2其他魔法方法

  • __mul__(self, other)定義乘法的行為:*
  • __truediv__(self, other)定義真除法的行為:/
  • __floordiv__(self, other)定義整數除法的行為://
  • __mod__(self, other) 定義取模演算法的行為:%
  • __divmod__(self, other)定義當被 divmod() 呼叫時的行為
    • divmod(a, b)把除數和餘數運算結果結合起來,返回一個包含商和餘數的元組(a // b, a % b)
    print(divmod(7, 2))  # (3, 1)
    print(divmod(8, 2))  # (4, 0)
    
  • __pow__(self, other[, module])定義當被 power() 呼叫或 ** 運算時的行為
  • __lshift__(self, other)定義按位左移位的行為:<<
  • __rshift__(self, other)定義按位右移位的行為:>>
  • __and__(self, other)定義按位與操作的行為:&
  • __xor__(self, other)定義按位異或操作的行為:^
  • __or__(self, other)定義按位或操作的行為:|

2.3反運算

反運算魔方方法,與算術運算子保持一一對應,不同之處就是反運算的魔法方法多了一個“r”。當檔案左操作不支援相應的操作時被呼叫。

  • __radd__(self, other)定義加法的行為:+
  • __rsub__(self, other)定義減法的行為:-
  • __rmul__(self, other)定義乘法的行為:*
  • __rtruediv__(self, other)定義真除法的行為:/
  • __rfloordiv__(self, other)定義整數除法的行為://
  • __rmod__(self, other) 定義取模演算法的行為:%
  • __rdivmod__(self, other)定義當被 divmod() 呼叫時的行為
  • __rpow__(self, other[, module])定義當被 power() 呼叫或 ** 運算時的行為
  • __rlshift__(self, other)定義按位左移位的行為:<<
  • __rrshift__(self, other)定義按位右移位的行為:>>
  • __rand__(self, other)定義按位與操作的行為:&
  • __rxor__(self, other)定義按位異或操作的行為:^
  • __ror__(self, other)定義按位或操作的行為:|

a + b
這裡加數是a,被加數是b,因此是a主動,反運算就是如果a物件的__add__()方法沒有實現或者不支援相應的操作,那麼 Python 就會呼叫b__radd__()方法。

class Nint(int):
    def __radd__(self, other):
        return int.__sub__(other, self) # 注意 self 在後面
a = Nint(5)
b = Nint(3)
print(a + b)  # 沒有呼叫__radd__方法
# 8 
print(1 + b) # 沒有找到1的__add__方法,只找到b的__radd__方法
# -2 

3增量賦值運算子

  • __iadd__(self, other)定義賦值加法的行為:+=
  • __isub__(self, other)定義賦值減法的行為:-=
  • __imul__(self, other)定義賦值乘法的行為:*=
  • __itruediv__(self, other)定義賦值真除法的行為:/=
  • __ifloordiv__(self, other)定義賦值整數除法的行為://=
  • __imod__(self, other)定義賦值取模演算法的行為:%=
  • __ipow__(self, other[, modulo])定義賦值冪運算的行為:**=
  • __ilshift__(self, other)定義賦值按位左移位的行為:<<=
  • __irshift__(self, other)定義賦值按位右移位的行為:>>=
  • __iand__(self, other)定義賦值按位與操作的行為:&=
  • __ixor__(self, other)定義賦值按位異或操作的行為:^=
  • __ior__(self, other)定義賦值按位或操作的行為:|=

4一元運算子

  • __neg__(self)定義正號的行為:+x
  • __pos__(self)定義負號的行為:-x
  • __abs__(self)定義當被abs()呼叫時的行為
  • __invert__(self)定義按位求反的行為:~x

6 習題

1、上面提到了許多魔法方法,如__new__,__init__, __str__,__rstr__,__getitem__,__setitem__等等,請總結它們各自的使用方法。

  • __init__:構造器,當一個例項被建立的時候呼叫的初始化方法
  • __new__:返回一個例項物件,__new__方法返回類的例項物件,這個例項物件傳給__int__方法中定義的self引數。若__new__方法返回None,則不會呼叫__init__方法。
  • __str__:當你列印一個物件的時候,或者當你使用%s格式化的時候,str強轉資料型別的時候,會觸發__str__
  • __rstr__:反運算的魔法方法多了一個“r”。當檔案左操作不支援相應的操作時被呼叫。
  • __getitem__:定義獲取容器中元素的行為,相當於self[key]
  • __setitem__:定義設定容器中指定元素的行為,相當於self[key] = value

2、利用python做一個簡單的定時器類
要求:

  • 定製一個計時器的類。
  • startstop方法代表啟動計時和停止計時。
  • 假設計時器物件t1print(t1)和直接呼叫t1均顯示結果。
  • 當計時器未啟動或已經停止計時時,呼叫stop方法會給予溫馨的提示。
  • 兩個計時器物件可以進行相加:t1+t2
  • 只能使用提供的有限資源完成。
import time


class Mytime(object):
   def __init__(self):
       self.__info = '未開始計時!'
       self.__begin = None
       self.__end = None
       self.__jg = 0

   def __str__(self):
       return self.__info

   def __repr__(self):
       return self.__info

   def start(self):
       print('計時開始...')
       self.__begin = time.localtime()

   def stop(self):
       if not self.__begin:
           print('提示:請先呼叫start()開始計時!')
           return
       self.__end = time.localtime()
       self.__jg = time.mktime(self.__end) - time.mktime(self.__begin)
       self.__info = '共執行了%d秒' % self.__jg
       print('計時結束!')
       return self.__jg

   def __add__(self, other):
       return '共執行了%d秒' % (other.__jg + self.__jg)

相關文章