python-工廠函數

在python2.2之前類與類型分開

:封裝(屬性+方法)
類型:整型、浮點型、字符型、字符串型

但之後作者對這倆統一了
將int()、str()、list()這些BIF轉化成了工廠函數。

int()與類d的class是一樣的,可以把工廠函數看成類,返回實例對象

type(int)
<class 'type'>
class d:
...     pass
... 
type(d)
<class 'type'>

將類int()進行實例化

a = int('123')
b = int('456')
a+b
579

以前上面的語句是將字符串類型改爲整型
現在則是將類int()實例化爲a,而“123‘’則是傳入的參數

語句:a+b,實際上是對象之間的操作

python專門使用魔法方法定義了對象之間的操作

例如:當檢測到對象之間用+號操作時,自動調用int()類中的__add__方法(魔法方法,在需要的時候自動被調用,就像__init__)

下面創建新的類來繼承int()的所有方法,然後通過改寫__add__方法來讓+號不執行相加操作,反而執行相減操作

class re_int(int):

    def __add__(self, other):  # 檢測到對象間“+”號,自動執行該方法
        return int.__sub__(self, other)  # 返回值爲:int()類中的相減操作

    def __sub__(self, other):  # 檢測到對象間“-”號,自動執行該方法
        return int.__add__(self, other)  # 返回值爲:int()類中的相加操作

a = re_int('5')
b = re_int('3')
print(a + b)
2  # 運行結果

如此,我們在類re_int()中交換了符號“+”與符號“-”的作用,使由類產生的實例化對象a與b在執行符號:“+”與“-”的操作時並不像通常認知的那樣。

我們彷彿深入到了更加底層的代碼,上帝之手像你召喚喚喚喚喚!!!

下面讓我們來康康父類int()中的魔法方法是如何實現的:

(dir(類名):查看類中所有方法名和屬性名)
(help(類名.方法名):查看類中方法)

help(int.__add__)
Help on wrapper_descriptor:
__add__(self, value, /)
    Return self+value.
help(int.__sub__)
Help on wrapper_descriptor:
__sub__(self, value, /)
    Return self-value.

上面我們看到了int()類中add方法的實現過程

如果將我們的re_int類不繼承int而是自己定義add方法能實現實例對象的加法運算嗎?

class re_int(int):

    def __add__(self, other,/):  # 檢測到對象間“+”號,自動執行該方法
        return self+other # 返回值爲:int()類中的相減操作

    def __sub__(self, other,/):  # 檢測到對象間“-”號,自動執行該方法
        return self-other # 返回值爲:int()類中的相加操作
a = re_int('5')
b = re_int('3')
print(a+b)

運行結果發現超出做大遞歸數

Traceback (most recent call last):
  File "D:/FishC/作業/41_48_魔法方法/11.py", line 17, in <module>
    print(a+b)
  File "D:/FishC/作業/41_48_魔法方法/11.py", line 8, in __add__
    return self+other # 返回值爲:int()類中的相減操作
  File "D:/FishC/作業/41_48_魔法方法/11.py", line 8, in __add__
    return self+other # 返回值爲:int()類中的相減操作
  File "D:/FishC/作業/41_48_魔法方法/11.py", line 8, in __add__
    return self+other # 返回值爲:int()類中的相減操作
  [Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded

要想正確運行可以在返回前面加上int(),這樣返回的是整型的相加

class re_int(int):

    def __add__(self, other,/):  # 檢測到對象間“+”號,自動執行該方法
        return int(self)+int(other) # 返回值爲:int()類中的相減操作

    def __sub__(self, other,/):  # 檢測到對象間“-”號,自動執行該方法
        return int(self)-int(other) # 返回值爲:int()類中的相加操作
a = re_int('5')
b = re_int('3')
print(a+b)

例子1:

兩個字符串相加會自動拼接字符串,但遺憾的是兩個字符串相減卻拋出異常。
因此,現在我們要求定義一個 Nstr 類,支持字符串的相減操作:
A – B,從 A 中去除所有 B 的子字符串

class Nstr(str):

    def __sub__(self, other):
        for each in other:
            if each in self:
                self = self.replace(each, '')
        return str(self)

運行結果:
Nstr類繼承str類的所有屬性和方法:

檢測到減號自動調用__sub__魔法方法
(雖然str類中沒有__sub__方法,但是子類Nstr產生的實例遇到“-”號仍然會自動運行__sub__方法)

self是a,other是b
(a與b都是同一個類產生的對象,所以能調用共同的類方法進行操作)

>>> a = Nstr('I love FishC.com!iiiiiiii')
>>> b = Nstr('i')
>>> print(a - b)

I love FshC.com!

例子2:
#定義一個類 Nstr
#當該類的實例對象間發生的加、減、乘、除運算時
#將該對象的所有字符串的 ASCII 碼之和進行計算
#查看ASCII: ord(字符)


class Nstr(str):

    def __add__(self, other):	# 遇到符號:+   自動運行魔法方法__add__(NB)
        s1 = 0
        s2 = 0
        for each in self:
            s1 += int(ord(each))
        for each in other:
            s2 += int(ord(each))
        return s1 + s2

    def __sub__(self, other):
        s1 = 0
        s2 = 0
        for each in self:
            s1 += int(ord(each))
        for each in other:
            s2 += int(ord(each))
        return s1 - s2

    def __mul__(self, other):
        s1 = 0
        s2 = 0
        for each in self:
            s1 += int(ord(each))
        for each in other:
            s2 += int(ord(each))
        return s1 * s2

    def __truediv__(self, other):
        s1 = 0
        s2 = 0
        for each in self:
            s1 += int(ord(each))
        for each in other:
            s2 += int(ord(each))
        return s1 / s2
        

運行結果:


>>> a = Nstr('FishC')
>>> b = Nstr('love')
print(a+b,a-b,a*b,a/b)

899 23 201918 1.052511415525114

通過以上兩個算例我們可以看出:

雖然python沒有給我們提供需要的底層功能(比如字符串減法等)

但有了工廠函數我們可以根據需要自己定義需要的功能

這使我們的編程更加的靈活

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章