App下載

人工智能和機(jī)器學(xué)習(xí)系列(三) Python 生成器和類

陪你演戲 2021-08-24 10:57:05 瀏覽數(shù) (2948)
反饋

簡(jiǎn)介

這是我們學(xué)習(xí) Python 及其在機(jī)器學(xué)習(xí) (ML) 和人工智能 (AI) 中的應(yīng)用系列中的第三個(gè)模塊。在上一個(gè)模塊中,我們了解了數(shù)據(jù)結(jié)構(gòu)和循環(huán)?,F(xiàn)在讓我們更深入地了解生成器和類。

生成器

創(chuàng)建自己的迭代器的一種方法是使用生成器函數(shù)。生成器函數(shù)使用yield關(guān)鍵字將下一個(gè)迭代器值傳遞給調(diào)用者。這類似于yield returnC# 中的關(guān)鍵字。一旦函數(shù)返回,就沒有什么可以迭代的了。

讓我們yield使用生成器函數(shù)來演示關(guān)鍵字,該函數(shù)生成斐波那契數(shù)列的前n 個(gè)數(shù)字:

def fibonacci(n):
    a = 1
    b = 1
    for i in range(n):
        if i < 2:
            yield 1
        else:
            c = a + b
            a = b
            b = c
            yield c

您現(xiàn)在可以像使用諸如 之類的函數(shù)一樣使用此函數(shù)range,例如在循環(huán)中:

for f in fibonacci(10):
    print(f)

這將打印前十個(gè)斐波那契數(shù)。

您還可以使用生成器函數(shù)生成無限多個(gè)元素。

與 C# 或 Java 一樣,Python 也有類。Python 提供了面向?qū)ο缶幊痰乃袠?biāo)準(zhǔn)特性。

讓我們來看看 Python 中一個(gè)簡(jiǎn)單類的示例:

from math import sqrt

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

    def length(self):
        return sqrt(self.x ** 2 + self.y ** 2)

__init__方法是構(gòu)造函數(shù)。

length 是一個(gè)類方法

類方法的第一個(gè)參數(shù)是指正在處理的類實(shí)例。按照慣例,這稱為self。(您可以將其命名為其他名稱,但從來沒有人這樣做過。) 的作用self很像thisC# 和 Java 中的作用,即對(duì)當(dāng)前對(duì)象的引用。Python 中的不同之處在于不能只使用x而不是self.x,并且 Python 要求您將其顯式包含為第一個(gè)方法參數(shù)。

您現(xiàn)在可以像這樣使用該類:

v = Vector(1, 1)
print(v.length())
print(v.x)
print(v.y)

xy屬性可當(dāng)你看到上面的訪問,但是它們可以被修改,以及:

v.x = 2
print(v.length())

Python 沒有諸如publicand 之類的訪問修飾符private。所有變量都可以公開訪問。以下劃線開頭的屬性名稱是一種告訴您的類的用戶他們不應(yīng)該使用該屬性的方法,但這不是語言強(qiáng)制執(zhí)行的。

繼承

讓我們演示如何從 Python 中的類派生。我們將創(chuàng)建一個(gè)基類 Document 和一個(gè)派生類 Book:

class Document:
    def __init__(self, author, content):
        self.author = author
        self.content = content

    def length(self):
        return len(self.content)

    def info_summary(self):
        return "Document written by " + self.author

class Book(Document):
    def __init__(self, author, content, pages):
        super().__init__(author, content)
        self.pages = pages

    def info_summary(self):
        return "Book written by {} of {} pages".format(self.author, self.pages)

Book類派生自Document。在Book類的__init__方法中,這一行調(diào)用了超類的構(gòu)造函數(shù)。

super().__init__(author, content)

info_summary函數(shù)被 in 覆蓋Bookoverride不需要關(guān)鍵字之類的東西),并且沒有提及lengthinBook所以它只是從Document.

book = Book("me", "... content ...", 50)
print(book.length())
print(book.info_summary())

如果要檢查某個(gè)對(duì)象是否屬于某個(gè)類,請(qǐng)使用以下isinstance函數(shù):

print(isinstance(book, Book)) # True
print(isinstance(book, Document)) # True
print(isinstance(book, object)) # True

doc = Document("someone else", "...")
print(isinstance(doc, Book)) # False
print(isinstance(doc, Document)) # True

與 C# 和 Java 不同,Python 支持多重繼承:Book(Document)您可以編寫 class而不是編寫 class Book(Document, AnotherClass, PerhapsEvenMore)。

如果超類具有相同名稱的方法,則在子類中只能派生其中之一。當(dāng)一個(gè)方法被調(diào)用時(shí)(沒有被顯式覆蓋),Python 使用一個(gè)名為 C3 線性化的算法來確定在超類中查找的順序。如果要查看所謂的方法解析順序,可以查看YourClassName.__mro__屬性。這是一個(gè)人為的例子來證明

class A:
    pass

class B:
    pass

class C:
    pass

class D(A, C):
    pass

class F(B, C):
   pass

class G(A):
    pass

class H(F, B, D, A):
    pass

print(H.__mro__)

這個(gè)輸出(<class '__main__.H'>, <class '__main__.F'>, <class '__main__.B'>, <class '__main__.D'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>)讓你知道 Python 將首先查看 H 類,然后是 B、D、A,最后是 C。

魔術(shù)方法

Python 類提供了許多“魔術(shù)方法”,允許您進(jìn)行運(yùn)算符重載、將類實(shí)例視為迭代器等等。

魔術(shù)方法就像普通方法一樣,但具有特定名稱的格式__method_name__。你已經(jīng)知道一種神奇的方法,__init__。另一個(gè)例子是__add__魔術(shù)方法,用于重載+運(yùn)算符:

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

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

v1 = Vector(3, 2)
v2 = Vector(4, 1)
v3 = v1 + v2

__iter____next__魔術(shù)方法使您能夠在實(shí)例迭代。此方法返回下一個(gè)迭代值或引發(fā)StopIteration以指示結(jié)束。

class Fibonacci:
    def __init__(self, n):
        self.prev = 1
        self.prev_prev = 1
        self.n = n
        self.i = 0

    def __iter__(self):
        return self

    def __next__(self):
        self.i += 1
        if self.i == self.n + 1:
            raise StopIteration
        if self.i <= 2:
            return 1
        else:
            current = self.prev + self.prev_prev
            self.prev_prev = self.prev
            self.prev = current
            return current

for fib in Fibonacci(10):
    print(fib)

這只是魔術(shù)方法的表面,您可以做的還有很多。

結(jié)論

在本模塊中,我們討論了迭代器、類、繼承和魔術(shù)方法的生成器函數(shù)?,F(xiàn)在我們已經(jīng)了解了 Python 基礎(chǔ)知識(shí),接下來的模塊,我們就可以開始接觸人工智能和機(jī)器學(xué)習(xí)相關(guān)的內(nèi)容了。


0 人點(diǎn)贊