簡(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 return
C# 中的關(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
很像this
C# 和 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)
該x
和y
屬性可當(dāng)你看到上面的訪問,但是它們可以被修改,以及:
v.x = 2
print(v.length())
Python 沒有諸如public
and 之類的訪問修飾符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 覆蓋Book
(override
不需要關(guān)鍵字之類的東西),并且沒有提及length
inBook
所以它只是從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)容了。