【问题标题】:Python for loop iterate only oncePython for 循环只迭代一次
【发布时间】:2021-07-30 10:47:38
【问题描述】:

基本问题,但让我很困惑。

我有一个大约 4300 行的 csv 文件。

我需要将每一行发送到一个有大小限制的服务,所以我不能一次处理所有行。

所以我的想法是有一个函数,它为 csv 文件中的每一行触发一个 for 循环。

这就是我所做的。

with open('final_result.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        to_queue.append(row)

for msg in to_queue:
    # print(msg)
    def send_a_list_of_messages(sender):
        # print(to_queue)
        message = [ServiceBusMessage(str(msg))]
        sender.send_messages(message)
        print("msg sent: " + str(msg))

我对此的期望是,msg 应该以渐进方式从 csv 文件中获取每个值,将其传递给函数并发送。

在某种程度上,这就是发生的情况,但它确实只发送 csv 文件的 last 行。 我想知道我在这做错了什么?如何让这个 for 循环触发 csv 中每一行的内部函数?

编辑:

这是整个代码:

def send_a_list_of_messages(sender):
    # print(to_queue)
    message = ServiceBusMessage(str(msg))
    sender.send_messages(message)
    print("msg sent: " + str(msg))

with open('final_result.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        to_queue.append(row)

for msg in to_queue:
    send_a_list_of_messages(msg)



servicebus_client = ServiceBusClient.from_connection_string(conn_str=CONNECTION_STR, logging_enable=True)
#
with servicebus_client:
    sender = servicebus_client.get_queue_sender(queue_name=QUEUE_NAME)
    with sender:
        send_a_list_of_messages(sender)

print("Done sending messages")
print("-----------------------")

with servicebus_client:
    receiver = servicebus_client.get_queue_receiver(queue_name=QUEUE_NAME, max_wait_time=5)
    with receiver:
        for msg in receiver:
            print("Received: " + str(msg))
            receiver.complete_message(msg)

该函数在 service_client 中调用

【问题讨论】:

  • 为什么要在循环中定义函数?
  • 因为我使用的 azure 服务对消息有大小限制。而那个函数是发送一定大小的消息的关键。这就是我想在循环中使用该函数的原因,所以我确保该函数一次发送 1 行
  • 当您在for 循环内定义一个函数时,如果您不在for 循环内调用该函数,则只有最后一个函数定义仍然存在。您能否举例说明该函数是如何被调用或在何处传递的?
  • @Axe319 我用代码更新了我的帖子
  • 你能不能把to_queue list 作为参数(send_a_list_of_messages) 传递给你的函数中的for msg in to_queue: message = ServiceBusMessage(str(msg)) : sender.send_messages(message)

标签: python-3.x for-loop


【解决方案1】:

你需要在调用它之前定义你的函数。在您发布的示例中,您重复定义了您的函数,但没有调用它。所以,你需要定义函数,然后在循环中调用它。

编辑:我在编辑后调整了代码,您的问题似乎是在您尝试发送消息之前未为发件人分配值。

def send_a_list_of_messages(sender, msg):
    # print(to_queue)
    message = ServiceBusMessage(str(msg))
    sender.send_messages(message)
    print("msg sent: " + str(msg))

with open('final_result.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        to_queue.append(row)

servicebus_client = ServiceBusClient.from_connection_string(conn_str=CONNECTION_STR, logging_enable=True)
sender = servicebus_client.get_queue_sender(queue_name=QUEUE_NAME)

for msg in to_queue:
    send_a_list_of_messages(sender, msg)

print("Done sending messages")
print("-----------------------")

receiver = servicebus_client.get_queue_receiver(queue_name=QUEUE_NAME, max_wait_time=5)
for msg in receiver:
    print("Received: " + str(msg))
    #I'm not certain what the receiver.complete_message does, but remember that you call this in a loop.
    receiver.complete_message(msg)

【讨论】:

  • 我尝试了这个解决方案,但我在 for 循环中收到了发件人 unresolved reference sender 的编译器错误
【解决方案2】:

在目前的形式下,由于一些原因,它无法工作。

当您在 for 循环中重新定义函数时,它会隐藏(覆盖)该函数的前一次迭代。所以只有最终的定义存在。

您可以采取一些措施来解决此问题。

  1. 直接将消息的list传递给函数:
def send_a_list_of_messages(sender, messages):
    for msg in messages:
        message = ServiceBusMessage(str(msg))
        sender.send_messages(message)
        print("msg sent: " + str(msg))

to_queue = []
with open('final_result.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        to_queue.append(row)

servicebus_client = ServiceBusClient.from_connection_string(
    conn_str=CONNECTION_STR, 
    logging_enable=True
)
with servicebus_client:
    sender = servicebus_client.get_queue_sender(queue_name=QUEUE_NAME)
    with sender:
        send_a_list_of_messages(sender, to_queue)
  1. 循环调用函数。
def send_a_single_message(sender, msg):
    message = ServiceBusMessage(str(msg))
    sender.send_messages(message)
    print("msg sent: " + str(msg))

to_queue = []
with open('final_result.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        to_queue.append(row)

servicebus_client = ServiceBusClient.from_connection_string(
    conn_str=CONNECTION_STR, 
    logging_enable=True
)
with servicebus_client:
    sender = servicebus_client.get_queue_sender(queue_name=QUEUE_NAME)
    with sender:
        for msg in to_queue:
            send_a_single_message(sender, msg)

最好以参数的形式包含函数所需的所有内容,而不是依赖外部变量。

例如,如果您不将msg 作为参数传递,它只会在msg 在同一文件中外部定义的条件下起作用。这不会促进可重用性。

【讨论】:

    最近更新 更多