当方法没有 return 语句时,如何打印出它的 return 值?
When a method has no return statement, how do I print out it's return value?
已编辑。
我正在学习链表。对于方法应用的每个过程,它都会打印到控制台。因此,添加、删除、搜索(即显示搜索结果)都流式传输到 stdout
,但我似乎无法为插入方法执行此操作,即使执行了 insert
方法.
一些方法有一个 return 语句,而其他方法则依赖 __repr__()
转换为字符串,然后流式传输到控制台。插入方法(不是我的,而是一个课程示例)采用 两个 参数并且没有 return 语句。我尝试打印时收到的最一致的错误消息是 TypeError: %d format: a real number is required, not NoneType
或 TypeError: not enough arguments for format string
,其中我已将 %d
替换为 %s
。
我不明白的是,为什么我无法为插入方法显示测试数据,而我可以为所有其他方法显示测试数据。
代码,
#!/usr/bin/env python3
class Node:
data = None
next_node = None
def __init__(self, data):
self.data = data
def __repr__(self):
return "<Node data: {}>".format(self.data)
# Linked List
class LinkedList:
def __init__(self):
self.head = None
def is_empty(self):
return self.head == None # corrected
def size(self):
current = self.head
count = 0
while current:
count += 1
current = current.next_node
return count
# Adding a node
def add(self, data):
new_node = Node(data)
new_node.next_node = self.head
self.head = new_node
# Searching the List
def search(self, key):
current = self.head
while current:
if current.data == key:
return current
else:
current = current.next_node
return None
# Inserting into the List
def insert(self, data, index):
if index == 0:
self.add(data)
if index > 0:
new_data = Node(data)
position = index
current = self.head
while position > 1:
current = current.next_node
position -= 1
past_node = current
future_node = current.next_node
past_node.next_node = new_data
new_data = current.next_node
# Removing a node from the List
def remove(self, key):
current = self.head
previous = None
found = False
while current and not found:
if current.data == key and current == self.head:
found = True
self.head = current.next_node
elif current.data == key:
found = True
previous.next_node = current.next_node
return current
def __repr__(self):
nodes = []
current = self.head
while current:
if current is self.head:
nodes.append("[Head: {}]".format(current.data))
elif current.next_node is None:
nodes.append("[Tail {}]".format(current.data))
else:
nodes.append("[{}]".format(current.data))
current = current.next_node
return '-> '.join(nodes)
测试输出;
l = LinkedList()
l.add(1)
l.add(2)
l.add(3)
l.add(5)
l.add(6)
l.add(7)
length = l.size()
print("Size of list: {}".format(length)) # Size of list: 6
print(l) # [Head: 7]-> [6]-> [5]-> [3]-> [2]-> [Tail: 1]
seek = l.search(7)
print("Found: {}".format(seek)) # Found: <Node data: 7>
between = l.insert(4, 3)
if between is not None:
print(f"Inserted {between} at index {between}")
else:
print("A problem with code") # A problem with code
gone = l.remove(1)
print("Removed: {}".format(gone)) # Removed: <Node data: 1>
# Note the insertion of '4' at index 3
print(l) # [Head: 7]-> [6]-> [5]-> [4]-> [3]-> [Tail: 2]
此代码有效!
已尝试打印格式的其他变体 f"{}", .format()
,甚至尝试转换为字符串 str()
,但没有成功。有人可以准确解释问题是什么(虽然,我认为这是一个 NoneType 问题)以及如何解决它?
我希望我的问题更清楚。谢谢。
我认为您混淆了两件事。 return 语句后的值是调用函数时替换为函数调用的值。例如:
def square(x):
return x*x
square(4)
这里的 square(4) 将被替换为 4*4。如果您没有明确使用 return 语句,那么 None 会在 function/method.
中的最后一个命令之后被 returned
而 repr() 是一种指定该对象的字符串表示形式的方法。例如:
class A:
pass
a = A()
print(a)
可能会创建 <main.A at 0x7fbc841c9490> 的神秘输出。所以如果你想让它更具描述性,你可以添加一个 repr() 方法:
class Point:
def __init__(self, x,y):
self.x = x
self.y = y
def __repr__(self):
return f"Coordinates of the point are x: {self.x}, y: {self.y}"
p = Point(2,4)
您会收到以下神秘的默认消息:
Coordinates of the point are x: 2, y: 4
所以表示是如何将 obj 转换为字符串,而 return 值是函数调用被替换的内容。
print is TypeError: %d format: a real number is required, not
NoneType, or TypeError: not enough arguments for format string, where
I have replaced %d with %s.
所以这会产生错误,因为当没有 return 的方法的 return 类型是 None 时,%d 和 %s 需要数字和字符串。
insert
在输出数据时没有“问题”——就像标准的 Python 列表一样,它是一个 in-place 操作。您正在修改应用它的列表。
insert()
不需要 return 任何东西,因为你需要的所有信息都在调用它时由你提供 - 你需要传递一个列表,你需要传递数据来插入和您需要传递放置元素的索引 - returning 任何内容都不会获得新信息。
相关问题:
Why don't list operations return the resulting list?
您提供的代码存在几个问题,包括:
Node
class 不应将 data
和 next_node
定义为 class 属性。它们应该是实例属性。幸运的是,构造函数创建了一个实例属性 data
(隐藏了 class 属性),但是对于 next_node
这并没有完成,这使得您的链表无法使用。
根据前面的评论,你的构造函数中应该有self.next_node = None
。
[您在对问题的编辑中更正了这一点:方法名称is_empty表明它将return一个布尔值指示列表是否为空。但相反,它使列表为空。这似乎是错误的。]
[您在对问题的编辑中更正了此问题:insert
可以调用未定义的方法 add。]
在insert
中,当index
为0时,代码仍会在第一个if
之后继续并引用一个变量new_data
未定义(因为第二个 if
条件不成立)。您应该避免在 index
为 0 时执行任何其他代码。您可以使用 return
.
来执行此操作
在insert
中,在while
循环中没有验证current
是否为None
。如果发生这种情况,current = current.next_node
将引发错误。
new_data = current.next_node
没有用,并且未初始化 next_node
的 next_node
属性。
不是问题,但在 remove
中,found
名称不是很有用。找到并删除节点后,就跳出循环。此外,避免对同一节点执行两次 current.data == key
条件。
在 remove
循环中,您永远不会更改 current
或 previous
,因此循环挂起。
[您在对问题的编辑中更正了这一点:在主代码中,列表在 l.insert
时是空的调用,因此将 3 作为 index
参数的值传递很奇怪,因为该索引超出范围。如上一条项目符号中所述,这将触发错误。如果要在索引 3 处添加节点,则必须首先在索引 0、1 和 2 处添加节点。]
insert
方法没有 return 任何东西,因此捕获它的 return 值除了 None
之外不会给你任何其他东西。如果你真的想从中得到一些反馈,那么就像你对 remove
方法所做的那样:让它 return 相关节点。在那种情况下,您还应该让 add
具有 return 值。
这是一些工作代码,解决了上述问题以及更多问题:
class Node:
def __init__(self, data):
self.data = data
self.next_node = None # next_node neads to be an instance attribute, not a class attribute
def __repr__(self):
return "<Node data: {}>".format(self.data)
class LinkedList:
def __init__(self):
self.head = None
def is_empty(self):
return self.head == None # Don't MAKE it empty!
def size(self):
current = self.head
count = 0
while current:
count += 1
current = current.next_node
return count
def add(self, data):
new_node = Node(data)
new_node.next_node = self.head
self.head = new_node
return new_node # Return the new node
def search(self, key):
current = self.head
while current:
if current.data == key:
return current
else:
current = current.next_node
return None
def insert(self, data, index):
if index == 0:
# Don't continue after this call to self.add
return self.add(data) # Return the new node
current = self.head
while index > 1 and current: # Protect against out of range index
current = current.next_node
index -= 1
if current: # Protect against out of range index
new_data = Node(data)
# Make sure the new node gets a next_node assignment
new_data.next_node = current.next_node
current.next_node = new_data
return new_data # Return the new node
def remove(self, key):
current = self.head
previous = None
while current:
if current.data == key: # Check this only once per node
if current == self.head:
self.head = current.next_node
else:
previous.next_node = current.next_node
break # No need for variable - just exit
previous = current # Update previous
current = current.next_node # Move to next node
return current
def __repr__(self):
nodes = []
current = self.head
while current:
if current is self.head:
nodes.append("[Head: {}]".format(current.data))
elif current.next_node is None:
nodes.append("[Tail {}]".format(current.data))
else:
nodes.append("[{}]".format(current.data))
current = current.next_node
return '-> '.join(nodes)
l = LinkedList()
l.add(1)
l.add(2)
l.add(3)
l.add(5)
l.add(6)
l.add(7)
length = l.size()
print("Size of list: {}".format(length)) # Size of list: 6
print(l) # [Head: 7]-> [6]-> [5]-> [3]-> [2]-> [Tail: 1]
seek = l.search(7)
print("Found: {}".format(seek)) # Found: <Node data: 7>
node = l.insert(4, 3)
print("Inserted {}".format(node)) # Inserted: <Node data: 4>
gone = l.remove(1)
print("Removed: {}".format(gone)) # Removed: <Node data: 1>
# Note the insertion of '4' at index 3
print(l) # [Head: 7]-> [6]-> [5]-> [4]-> [3]-> [Tail: 2]
已编辑。
我正在学习链表。对于方法应用的每个过程,它都会打印到控制台。因此,添加、删除、搜索(即显示搜索结果)都流式传输到 stdout
,但我似乎无法为插入方法执行此操作,即使执行了 insert
方法.
一些方法有一个 return 语句,而其他方法则依赖 __repr__()
转换为字符串,然后流式传输到控制台。插入方法(不是我的,而是一个课程示例)采用 两个 参数并且没有 return 语句。我尝试打印时收到的最一致的错误消息是 TypeError: %d format: a real number is required, not NoneType
或 TypeError: not enough arguments for format string
,其中我已将 %d
替换为 %s
。
我不明白的是,为什么我无法为插入方法显示测试数据,而我可以为所有其他方法显示测试数据。 代码,
#!/usr/bin/env python3
class Node:
data = None
next_node = None
def __init__(self, data):
self.data = data
def __repr__(self):
return "<Node data: {}>".format(self.data)
# Linked List
class LinkedList:
def __init__(self):
self.head = None
def is_empty(self):
return self.head == None # corrected
def size(self):
current = self.head
count = 0
while current:
count += 1
current = current.next_node
return count
# Adding a node
def add(self, data):
new_node = Node(data)
new_node.next_node = self.head
self.head = new_node
# Searching the List
def search(self, key):
current = self.head
while current:
if current.data == key:
return current
else:
current = current.next_node
return None
# Inserting into the List
def insert(self, data, index):
if index == 0:
self.add(data)
if index > 0:
new_data = Node(data)
position = index
current = self.head
while position > 1:
current = current.next_node
position -= 1
past_node = current
future_node = current.next_node
past_node.next_node = new_data
new_data = current.next_node
# Removing a node from the List
def remove(self, key):
current = self.head
previous = None
found = False
while current and not found:
if current.data == key and current == self.head:
found = True
self.head = current.next_node
elif current.data == key:
found = True
previous.next_node = current.next_node
return current
def __repr__(self):
nodes = []
current = self.head
while current:
if current is self.head:
nodes.append("[Head: {}]".format(current.data))
elif current.next_node is None:
nodes.append("[Tail {}]".format(current.data))
else:
nodes.append("[{}]".format(current.data))
current = current.next_node
return '-> '.join(nodes)
测试输出;
l = LinkedList()
l.add(1)
l.add(2)
l.add(3)
l.add(5)
l.add(6)
l.add(7)
length = l.size()
print("Size of list: {}".format(length)) # Size of list: 6
print(l) # [Head: 7]-> [6]-> [5]-> [3]-> [2]-> [Tail: 1]
seek = l.search(7)
print("Found: {}".format(seek)) # Found: <Node data: 7>
between = l.insert(4, 3)
if between is not None:
print(f"Inserted {between} at index {between}")
else:
print("A problem with code") # A problem with code
gone = l.remove(1)
print("Removed: {}".format(gone)) # Removed: <Node data: 1>
# Note the insertion of '4' at index 3
print(l) # [Head: 7]-> [6]-> [5]-> [4]-> [3]-> [Tail: 2]
此代码有效!
已尝试打印格式的其他变体 f"{}", .format()
,甚至尝试转换为字符串 str()
,但没有成功。有人可以准确解释问题是什么(虽然,我认为这是一个 NoneType 问题)以及如何解决它?
我希望我的问题更清楚。谢谢。
我认为您混淆了两件事。 return 语句后的值是调用函数时替换为函数调用的值。例如:
def square(x):
return x*x
square(4)
这里的 square(4) 将被替换为 4*4。如果您没有明确使用 return 语句,那么 None 会在 function/method.
中的最后一个命令之后被 returned而 repr() 是一种指定该对象的字符串表示形式的方法。例如:
class A:
pass
a = A()
print(a)
可能会创建 <main.A at 0x7fbc841c9490> 的神秘输出。所以如果你想让它更具描述性,你可以添加一个 repr() 方法:
class Point:
def __init__(self, x,y):
self.x = x
self.y = y
def __repr__(self):
return f"Coordinates of the point are x: {self.x}, y: {self.y}"
p = Point(2,4)
您会收到以下神秘的默认消息:
Coordinates of the point are x: 2, y: 4
所以表示是如何将 obj 转换为字符串,而 return 值是函数调用被替换的内容。
print is TypeError: %d format: a real number is required, not NoneType, or TypeError: not enough arguments for format string, where I have replaced %d with %s.
所以这会产生错误,因为当没有 return 的方法的 return 类型是 None 时,%d 和 %s 需要数字和字符串。
insert
在输出数据时没有“问题”——就像标准的 Python 列表一样,它是一个 in-place 操作。您正在修改应用它的列表。
insert()
不需要 return 任何东西,因为你需要的所有信息都在调用它时由你提供 - 你需要传递一个列表,你需要传递数据来插入和您需要传递放置元素的索引 - returning 任何内容都不会获得新信息。
相关问题: Why don't list operations return the resulting list?
您提供的代码存在几个问题,包括:
Node
class 不应将data
和next_node
定义为 class 属性。它们应该是实例属性。幸运的是,构造函数创建了一个实例属性data
(隐藏了 class 属性),但是对于next_node
这并没有完成,这使得您的链表无法使用。根据前面的评论,你的构造函数中应该有
self.next_node = None
。[您在对问题的编辑中更正了这一点:方法名称is_empty表明它将return一个布尔值指示列表是否为空。但相反,它使列表为空。这似乎是错误的。]
[您在对问题的编辑中更正了此问题:
insert
可以调用未定义的方法 add。]在
来执行此操作insert
中,当index
为0时,代码仍会在第一个if
之后继续并引用一个变量new_data
未定义(因为第二个if
条件不成立)。您应该避免在index
为 0 时执行任何其他代码。您可以使用return
.在
insert
中,在while
循环中没有验证current
是否为None
。如果发生这种情况,current = current.next_node
将引发错误。new_data = current.next_node
没有用,并且未初始化next_node
的next_node
属性。不是问题,但在
remove
中,found
名称不是很有用。找到并删除节点后,就跳出循环。此外,避免对同一节点执行两次current.data == key
条件。在
remove
循环中,您永远不会更改current
或previous
,因此循环挂起。[您在对问题的编辑中更正了这一点:在主代码中,列表在
l.insert
时是空的调用,因此将 3 作为index
参数的值传递很奇怪,因为该索引超出范围。如上一条项目符号中所述,这将触发错误。如果要在索引 3 处添加节点,则必须首先在索引 0、1 和 2 处添加节点。]insert
方法没有 return 任何东西,因此捕获它的 return 值除了None
之外不会给你任何其他东西。如果你真的想从中得到一些反馈,那么就像你对remove
方法所做的那样:让它 return 相关节点。在那种情况下,您还应该让add
具有 return 值。
这是一些工作代码,解决了上述问题以及更多问题:
class Node:
def __init__(self, data):
self.data = data
self.next_node = None # next_node neads to be an instance attribute, not a class attribute
def __repr__(self):
return "<Node data: {}>".format(self.data)
class LinkedList:
def __init__(self):
self.head = None
def is_empty(self):
return self.head == None # Don't MAKE it empty!
def size(self):
current = self.head
count = 0
while current:
count += 1
current = current.next_node
return count
def add(self, data):
new_node = Node(data)
new_node.next_node = self.head
self.head = new_node
return new_node # Return the new node
def search(self, key):
current = self.head
while current:
if current.data == key:
return current
else:
current = current.next_node
return None
def insert(self, data, index):
if index == 0:
# Don't continue after this call to self.add
return self.add(data) # Return the new node
current = self.head
while index > 1 and current: # Protect against out of range index
current = current.next_node
index -= 1
if current: # Protect against out of range index
new_data = Node(data)
# Make sure the new node gets a next_node assignment
new_data.next_node = current.next_node
current.next_node = new_data
return new_data # Return the new node
def remove(self, key):
current = self.head
previous = None
while current:
if current.data == key: # Check this only once per node
if current == self.head:
self.head = current.next_node
else:
previous.next_node = current.next_node
break # No need for variable - just exit
previous = current # Update previous
current = current.next_node # Move to next node
return current
def __repr__(self):
nodes = []
current = self.head
while current:
if current is self.head:
nodes.append("[Head: {}]".format(current.data))
elif current.next_node is None:
nodes.append("[Tail {}]".format(current.data))
else:
nodes.append("[{}]".format(current.data))
current = current.next_node
return '-> '.join(nodes)
l = LinkedList()
l.add(1)
l.add(2)
l.add(3)
l.add(5)
l.add(6)
l.add(7)
length = l.size()
print("Size of list: {}".format(length)) # Size of list: 6
print(l) # [Head: 7]-> [6]-> [5]-> [3]-> [2]-> [Tail: 1]
seek = l.search(7)
print("Found: {}".format(seek)) # Found: <Node data: 7>
node = l.insert(4, 3)
print("Inserted {}".format(node)) # Inserted: <Node data: 4>
gone = l.remove(1)
print("Removed: {}".format(gone)) # Removed: <Node data: 1>
# Note the insertion of '4' at index 3
print(l) # [Head: 7]-> [6]-> [5]-> [4]-> [3]-> [Tail: 2]