目录
PyVarObject是什么文件,它里面的ob_size属性又是什么?
写在前面
《流畅的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