Python __iter__ 和 __repr__ 他们在做什么?

问题描述 投票:0回答:5

我目前正在 LinkedList 上工作,我有以下代码,但我不明白

__iter__
__repr__
到底在做什么?

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

class LinkedList:
    def __init__(self):
        self.head = None

    def append(self, value):
        if self.head is None:
            self.head = Node(value)
            return

        node = self.head
        while node.next:
            node = node.next

        node.next = Node(value)

    def __iter__(self):
        node = self.head
        while node:
            yield node.value
            node = node.next

    def __repr__(self):
        return str([v for v in self])

我在这里创建 LinkedList 并将值附加到列表末尾。

llist = LinkedList()
for value in [4,2,5,1,-3,0]:
    llist.append(value)

如果我打印列表

print(llist)
那么我会得到
[4, 2, 5, 1, -3, 0]

我猜这是来自

__iter__
__repr__
。我不明白的是我的
__iter__
__repr__
何时启动,哪个先运行?如何打印班级外的对象?

python
5个回答
1
投票

根据我对 Python 内部结构的有限理解,当您

print()
一个对象时,会在其上调用
str()
函数。这个函数可能知道如何格式化某些类型的对象,例如字符串和数字,对于其他对象,它调用它们的
__repr__()
方法,该方法应该返回一个字符串。所以首先调用
__repr__()

__repr__()
方法由开发人员编写,用于返回由列表理解
[v for v in self]
创建的普通列表表示形式。迭代最终调用
__iter__()
方法,它是一个生成器函数(如使用
yield
所示)。此函数迭代列表的元素,每个
yield
都会使一个元素可供
for ... in ...
构造使用。


0
投票

阅读文档

iter:定义什么属性/如何迭代类的对象应该工作 - 例如什么是“下一步”。如果您想说对动物进行迭代,并且希望迭代由每个动物的体重定义,那么您可以在动物类中使用 self.weight,就像您现在使用 self.value 一样...... .

_ repr _:当你执行 print(my_Object) 时,Python 默认会定义一个表示 (repr)。您可以使用此功能重新定义。


0
投票

当您实现 iter 方法时,您正在更改循环列表的行为。

我的意思是当你调用时在正常的 for 循环中:

for l in list:
   print(l)

这就是幕后会发生的事情:

# create an iterator object from that iterable
iter_obj = iter(list)
# infinite loop
while True:
    try:
        # get the next item
        element = next(iter_obj)
        # do something with element
    except StopIteration:
        # if StopIteration is raised, break from loop
        break

因此,如果您在链表类中重新定义 iter 函数,您将重新定义迭代函数以及应该迭代迭代器返回的内容。

repr 基本相同,您重新定义对象的表示。例如,当您调用 print(obj) 时,您会打印出 obj,但如果您按照自己的意愿正确实现了 repr,则可以将其更改为您想要的格式。

请查看此处以获取更多说明: https://www.programiz.com/python-programming/iterator https://www.pythonforbeginners.com/basics/str-vs-__repr


0
投票

__iter__
表示类的迭代器方法。我们通过代码来理解一下:

llist = LinkedList()
for value in [4,2,5,1,-3,0]:
    llist.append(value)
for value in llist:
    print(value)

输出

4
2
5
1
-3
0

这里,当我们将对象作为迭代器时,

__iter__()
方法将起作用,迭代并遍历链表并产生节点值。

print(llist)

输出

[4, 2, 5, 1, -3, 0]

在这里,

__repr__()
方法将起作用并打印代码中指定的节点值。


0
投票

例如

`class Node:
def __init__(self, value):
    self.value = value
    self.next = None

def __str__(self):
    if self.next is not None:
        return "Node\n value: %d \t next.value: %s " % (self.value, self.next.value)
    else:
        return "Node\n value: %d " % (self.value)
head = Node(34)
head.next = Node(38)

print(head)`

结果:

Node value: 34   next.value: 38 

在这个例子中,我们添加了一个str()函数,当打印出Company类的实例时,输出是employee_st。但是,我们没有显式调用 str() 函数,因为在实例上使用 print() 函数时,Python 的内部机制会自动调用 str() 函数。

类内部有很多像str()这样的函数,我们统称为魔术函数。现在,我们来明确一下魔法函数的类别: 魔术函数是指类中以双下划线开头并以双下划线结尾的函数。在特定的时间,Python会自动调用这些函数。魔法函数不是通过继承或其他机制获得的,但是一旦定义了一个类,Python的内部机制会自动将这些特殊函数分配给该类,并且用户无法创建魔法函数,即使函数名称以双下划线开头和结尾。通过神奇的功能,可以实现很多个性化、便捷的操作。

© www.soinside.com 2019 - 2024. All rights reserved.