《流畅的Python》学习笔记-第一章python的数据类型(二)

目录

写在前面

特殊方法的使用

使用内置函数调用

内置函数的数据类型有自己的调用方式

PyVarObject是什么文件,它里面的ob_size属性又是什么?

调用的时候可能是隐式的调用

什么是_iter_()

什么是__next__()

什么是迭代器


写在前面

《流畅的Python》(Fluent Python)是一本由Luciano Ramalho编写的Python编程书籍。这本书的目标是帮助中级到高级Python程序员更深入地理解Python编程语言,以及如何以更加Pythonic(符合Python惯用法)的方式编写代码。这本书不仅介绍了Python的基本语法和特性,还探讨了Python中的高级概念、最佳实践和一些常用的设计模式。

我将从2023年9月11日起更新学习这本书的一些笔记,本人基础较差所以学习起来会比较慢,内容也会比较详细~

特殊方法的使用

什么是python的特殊方法

是的,我知道如何使用Python的一些特殊方法。特殊方法(也称为魔法方法或双下划线方法)是Python中以双下划线开始和结束的方法(例如:__init__(), __str__()等)。这些方法在特定的情况下被Python解释器隐式调用,从而实现各种操作和行为。

使用内置函数调用

deck = FrenchDeck()# 创建一副扑克牌
print(deck.__len__())
print(len(deck))  # 内置函数,可读性和规范性更高

内置函数的数据类型有自己的调用方式

PyVarObject是什么文件,它里面的ob_size属性又是什么?

PyVarObject实际上不是一个文件,而是Python C API中定义的一个C结构体。它是PyObject结构体的扩展,用于表示可变长度(variable-sized)的Python对象,例如列表、元组和字符串等。PyVarObject包含一个名为ob_size的属性,该属性表示可变长度对象所容纳的元素个数。

在C API中,PyVarObject结构体的定义如下:

typedef struct {
    PyObject_VAR_HEAD
} PyVarObject;

PyObject_VAR_HEAD是一个宏,它扩展为包含ob_size属性的代码段:

PyObject_HEAD
Py_ssize_t ob_size; /* Number of items in variable part */

PyObject_HEAD是另一个宏,它定义了PyObject结构体的基本属性(如引用计数和类型信息)。在C API中,大多数Python对象都会包含PyObject_HEAD,它用于标识对象的类型和其他基本信息。

ob_size属性表示对象包含的变长部分的元素个数。对于各种Python对象,该属性的意义可能略有不同。例如,对于列表和元组,ob_size表示容器中元素的个数;对于字符串,ob_size表示字符串中字符的个数。不过,在某些情况下,ob_size可能不会反映真实的元素个数(例如,对于某些内部优化的字符串)。

总之,PyVarObject是Python C API中表示可变长度Python对象的底层C结构体,而ob_size属性用于表示对象中的元素个数

调用的时候可能是隐式的调用

在Python中,隐式调用通常指的是在某些操作或情境下,函数或方法会自动被执行,而无需显式地调用它们。这通常涉及到Python的特殊方法(也称为魔法方法,magic methods),这些方法都有两个下划线开始和结束(例如:__init__()__str__()等)。

当Python解释器遇到某些情境时(例如,实例化一个类、在for循环中遍历一个对象等),它会隐式地调用相应的特殊方法。

以下是一些隐式调用的例子:

构造函数(__init__():当实例化一个类时,__init__()方法会被隐式调用以初始化对象。

class SimpleCounter:
    def __init__(self, limit):
        self.limit = limit

    def __iter__(self):
        self.value = 0
        return self

    def __next__(self):
        if self.value < self.limit:
            self.value += 1
            return self.value
        else:
            raise StopIteration

counter = SimpleCounter(3)
for number in counter:  # 隐式调用 __iter__() 和 __next__() 方法
    print(number)

在上述示例中,我们可以看到__init__()__str__()__iter__()__next__()方法都是隐式调用的。这些特殊方法使得Python代码更为简洁易读,同时支持各种内置函数和操作。

class MyClass:
    def __str__(self):
        return "MyClass object in string form"

obj = MyClass()
print(obj)  # 输出 "MyClass object in string form"

可迭代对象(__iter__()__next__():当在for循环中遍历一个对象时,__iter__()方法会被隐式调用以获取迭代器,之后__next__()方法会被隐式调用以在序列中获取下一个元素。

class MyClass:
    def __init__(self):
        print("MyClass object has been initialized!")

obj = MyClass()  # 输出 "MyClass object has been initialized!"

字符串表示(__str__()__repr__():当尝试将对象转换为字符串或在控制台中显示对象时,__str__()__repr__()方法会被隐式调用。

什么是_iter_()

__iter__()是一个特殊方法,它在Python中被用于定义一个对象的迭代器协议。当一个对象实现了__iter__()方法时,该对象认为是可迭代的(iterable),这意味着我们可以在这个对象上使用for循环进行遍历。

__iter__()方法应返回一个迭代器对象,该迭代器需要实现__next__()方法,用于在遍历对象时获取下一个元素。

以下是一个使用__iter__()__next__()方法实现的简单可迭代对象示例:

class SimpleCounter:
    def __init__(self, limit):
        self.limit = limit

    def __iter__(self):
        self.value = 0
        return self

    def __next__(self):
        if self.value < self.limit:
            self.value += 1
            return self.value
        else:
            raise StopIteration

counter = SimpleCounter(5)
for number in counter:
    print(number)

在这个示例中,SimpleCounter类实现了__iter__()__next__()方法。__iter__()方法返回了self(迭代器对象),并将计数器值初始化为0。__next__()方法每次被调用时递增计数器值,并在达到限制值时引发StopIteration异常,告知for循环终止迭代。

在遍历counter对象时,将依次输出数字1到5。

什么是__next__()

__next__()是Python中的一个特殊方法,它在实现迭代器协议时使用。当一个对象需要作为迭代器使用时,它必须实现__next__()方法。在每次迭代时,__next__()方法会被调用以获取序列中的下一个元素。当迭代器没有更多的元素时,__next__()方法应引发StopIteration异常,通知迭代终止。

通常,具有__iter__()方法的可迭代对象(iterable)会返回一个实现了__next__()方法的迭代器(iterator)。

以下是一个简单的迭代器示例,它使用__next__()方法实现一个计数器:

class CounterIterator:
    def __init__(self, limit):
        self.limit = limit
        self.value = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.value < self.limit:
            self.value += 1
            return self.value
        else:
            raise StopIteration

counter = CounterIterator(5)
for number in counter:
    print(number)

在这个示例中,CounterIterator类实现了__iter__()__next__()方法。__iter__()方法返回了迭代器对象,__next__()方法负责每次递增计数器值。当计数器值达到限制值时,__next__()方法引发StopIteration异常,允许for循环终止迭代。

在遍历counter对象时,将依次输出数字1到5。

什么是迭代器

迭代器协议

(1)对象必须提供一个next()方法

(2)执行方法要吗返回迭代器中的下一项,要么输出一个Stopiteration异常

(3)只能向后不能向前

可迭代对象:实现了携带其协议的对象。(对象内壁定义一个__iter__()方法)

使用迭代器访问对象

Iterable:可迭代对象,内部包含__iter__()函数;(有迭代能力不一定是迭代器)

Iterator:迭代器,内部包含__iter__()和__next__().

常见的str,list,tuple,dict,set都是可迭代的。

from collections.abc import Iterable
from collections.abc import Iterator
l = [1,2,3]
l_iter = l.__iter__()
#检查是否是可迭代的对象
print(isinstance(l,Iterable)) #True
print(isinstance(l,Iterator)) #False
print(isinstance(l_iter,Iterator)) #True
print(isinstance(l_iter,Iterable)) #True
st="hello";
#先将字符串对象转化为可迭代对象
iterSt = st.__iter__()
while True:
    try:
        print(iterSt.__next__())
    except StopIteration:
        # print('迭代完成')
        break

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力毕业的每一天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值