Python生成器和类怎么使用
这篇文章主要讲解了"Python生成器和类怎么使用",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Python生成器和类怎么使用"吧!
生成器
创建自己的迭代器的一种方法是使用生成器函数。生成器函数使用yield
关键字将下一个迭代器值传递给调用者。这类似于yield return
C# 中的关键字。一旦函数返回,就没有什么可以迭代的了。
让我们yield
使用生成器函数来演示关键字,该函数生成斐波那契数列的前n 个数字:
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
您现在可以像使用诸如 之类的函数一样使用此函数range
,例如在循环中:
for f in fibonacci(10): print(f)
这将打印前十个斐波那契数。
您还可以使用生成器函数生成无限多个元素。
类
与 C# 或 Java 一样,Python 也有类。Python 提供了面向对象编程的所有标准特性。
让我们来看看 Python 中一个简单类的示例:
from math import sqrtclass Vector: def __init__(self, x, y): self.x = x self.y = y def length(self): return sqrt(self.x ** 2 + self.y ** 2)
该__init__
方法是构造函数。
length
是一个类方法
类方法的第一个参数是指正在处理的类实例。按照惯例,这称为self
。(您可以将其命名为其他名称,但从来没有人这样做过。) 的作用self
很像this
C# 和 Java 中的作用,即对当前对象的引用。Python 中的不同之处在于不能只使用x
而不是self.x
,并且 Python 要求您将其显式包含为第一个方法参数。
您现在可以像这样使用该类:
v = Vector(1, 1)print(v.length())print(v.x)print(v.y)
该x
和y
属性可当你看到上面的访问,但是它们可以被修改,以及:
v.x = 2print(v.length())
Python 没有诸如public
and 之类的访问修饰符private
。所有变量都可以公开访问。以下划线开头的属性名称是一种告诉您的类的用户他们不应该使用该属性的方法,但这不是语言强制执行的。
继承
让我们演示如何从 Python 中的类派生。我们将创建一个基类 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.authorclass 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__
方法中,这一行调用了超类的构造函数。
super().__init__(author, content)
该info_summary
函数被 in 覆盖Book
(override
不需要关键字之类的东西),并且没有提及length
inBook
所以它只是从Document
.
book = Book("me", "... content ...", 50)print(book.length())print(book.info_summary())
如果要检查某个对象是否属于某个类,请使用以下isinstance
函数:
print(isinstance(book, Book)) # Trueprint(isinstance(book, Document)) # Trueprint(isinstance(book, object)) # Truedoc = Document("someone else", "...")print(isinstance(doc, Book)) # Falseprint(isinstance(doc, Document)) # True
与 C# 和 Java 不同,Python 支持多重继承:Book(Document)
您可以编写 class而不是编写 class Book(Document, AnotherClass, PerhapsEvenMore)
。
如果超类具有相同名称的方法,则在子类中只能派生其中之一。当一个方法被调用时(没有被显式覆盖),Python 使用一个名为 C3 线性化的算法来确定在超类中查找的顺序。如果要查看所谓的方法解析顺序,可以查看YourClassName.__mro__
属性。这是一个人为的例子来证明
class A: passclass B: passclass C: passclass D(A, C): passclass F(B, C): passclass G(A): passclass H(F, B, D, A): passprint(H.__mro__)
这个输出(
让你知道 Python 将首先查看 H 类,然后是 B、D、A,最后是 C。
魔术方法
Python 类提供了许多"魔术方法",允许您进行运算符重载、将类实例视为迭代器等等。
魔术方法就像普通方法一样,但具有特定名称的格式__method_name__
。你已经知道一种神奇的方法,__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__
魔术方法使您能够在实例迭代。此方法返回下一个迭代值或引发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 currentfor fib in Fibonacci(10): print(fib)
感谢各位的阅读,以上就是"Python生成器和类怎么使用"的内容了,经过本文的学习后,相信大家对Python生成器和类怎么使用这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!