对象如何使用不在类内部或在任何地方定义的变量



在这段代码中,类Node的对象正在使用一个变量next,该变量在任何地方都没有定义,代码仍在工作?对象如何使用未在其类中定义的变量

class Node:
def __init__(self, data):
self.data = data
class LinkedList:
# Function to initialize head
def __init__(self):
self.head = None
# Function to reverse the linked list
def reverse(self):
prev = None
current = self.head
while(current is not None):
next = current.next
current.next = prev
prev = current
current = next
self.head = prev
# Function to insert a new node at the beginning
def push(self, new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node
# Utility function to print the linked LinkedList
def printList(self):
temp = self.head
while(temp):
print(temp.data)
temp = temp.next

llist = LinkedList()
llist.push(20)
llist.push(4)
llist.push(15)
llist.push(85)
print( "Given Linked List")
llist.printList()
llist.reverse()
print ("nReversed Linked List")
llist.printList()

虽然在大多数强类型语言中这是不可能的,但Python允许在创建实例并运行构造函数之后定义实例属性。只要代码在定义属性之前没有引用该属性,就没有问题。另请参阅:我可以在构造函数方法之外声明Python类字段吗?

在这种特殊情况下,以下代码将产生错误:

node = Node(42)
if node.next:  # Attribute error
print("42 is not the last node")
else:
print("42 is the last node")

但是,创建新节点实例的唯一位置是LinkedList类的push方法:

def push(self, new_data):
new_node = Node(new_data)
new_node.next = self.head
self.head = new_node

如您所见,next属性是在构造节点后立即定义的。因此,在实践中,链表中的每个节点都将具有next属性。

最佳实践

这种编码实践是否可取,还有待商榷。例如,Pylint有一个定义attr方法的规则,当属性在__init____new__setUp__post_init__之外定义时,默认情况下会引发警告。

备选方案

在这种情况下,我当然更喜欢在构造函数中定义next属性,并为构造函数提供一个额外的可选参数,用它可以初始化next

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

有了这个变化,LinkedList类的push方法可以简化为:

class LinkedList:
# ...
def push(self, new_data):
self.head = Node(new_data, self.head)

这看起来要优雅得多。

不相关,但我也会让LinkedList的构造函数接受任何数量的值来初始化列表:

class LinkedList:
def __init__(self, *values):
self.head = None
for value in reversed(values):
self.push(value)

现在,主代码可以一次创建一个包含4个值的列表:

llist = LinkedList(85, 15, 4, 20)

相关内容

  • 没有找到相关文章

最新更新