App下載

人工智能和機器學習系列(三) Python 生成器和類

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

簡介

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

生成器

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

讓我們yield使用生成器函數(shù)來演示關鍵字,該函數(shù)生成斐波那契數(shù)列的前n 個數(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)

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

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

與 C# 或 Java 一樣,Python 也有類。Python 提供了面向?qū)ο缶幊痰乃袠藴侍匦浴?/p>

讓我們來看看 Python 中一個簡單類的示例:

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__方法是構造函數(shù)。

length 是一個類方法

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

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

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

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

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

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

繼承

讓我們演示如何從 Python 中的類派生。我們將創(chuàng)建一個基類 Document 和一個派生類 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)用了超類的構造函數(shù)。

super().__init__(author, content)

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

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

如果要檢查某個對象是否屬于某個類,請使用以下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)。

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

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__)

這個輸出(<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。

魔術方法

Python 類提供了許多“魔術方法”,允許您進行運算符重載、將類實例視為迭代器等等。

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

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__魔術方法使您能夠在實例迭代。此方法返回下一個迭代值或引發(fā)StopIteration以指示結束。

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ù)。現(xiàn)在我們已經(jīng)了解了 Python 基礎知識,接下來的模塊,我們就可以開始接觸人工智能和機器學習相關的內(nèi)容了。


0 人點贊