Python生成器和类

目录

介绍

生成器

继承

魔术方法

结论


介绍

这是我们关于学习Python及其在机器学习(ML)和人工智能(AI)中的应用的系列文章中的第三个模块。在前面的模块中,我们研究了数据结构和循环。现在,让我们进一步介绍一下生成器和类。

生成器

创建自己的迭代器的一种方法是使用生成器函数。生成器函数使用yield关键字将下一个迭代器值传递给调用方。这类似于C#中的yield return关键字。一旦函数返回,就没有任何迭代的余地了。

让我们使用生成器函数演示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 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__方法是构造函数。

length 是一个类方法。

类方法的第一个参数是指正在处理的类实例。按照惯例,这称为self(您可以命名其他名称,但没人能做到这一点。)。self的作用与C#和Java(对当前对象的引用)中的this作用非常相似。Python的不同之处在于,您不能只使用x而是self.x,并且Python要求您明确地将其作为第一个方法参数。

您现在可以使用这样的类:

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

如你所见,xy属性可以被访问,但是它们也可以被修改:

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

Python没有访问修饰符,例如publicprivate。所有变量均可公开访问。用下划线开头的属性名称可以告诉类的用户他们不应该使用该属性,但是该语言不强制使用该名称。

继承

让我们演示如何从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.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__方法中,此行调用超类的构造函数。

super().__init__(author, content)

Book(不需要像override关键字一样)info_summary函数被覆盖,并且Book中没有提及length,因此它仅从Document派生出。

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

如果要检查某个对象是否属于某个类,请使用以下isinstance函数:

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, AnotherClass, PerhapsEvenMore)类而不是编写Book(Document)类。

如果超类具有相同名称的方法,则只能在子类中派生其中一个。调用方法时(未明确覆盖),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类中查找,然后是BDA,最后是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 current

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

这只是魔术方法的表面,您还可以做更多的事情。如果您有兴趣,请参阅本指南

结论

在本模块中,我们讨论了用于迭代器、类、继承和魔术方法的生成器函数。现在,我们已经了解了Python的基础知识,我们可以全面了解Python与机器学习相关的软件包

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值