异步 python 脚本刚刚在控制台中返回(在 IDE / 调试器中工作)

Async python script just returning in console (works in IDE / debugger)

该脚本 运行 在 rasperry 零上的 thonny 中运行良好,并完成其测量和与 mqtt 服务器交互的工作。这是一个在后台 运行s 的脚本,我将它添加到 /etc/rc.local 行 fi 和 exit 0 之间: python3 /home/pi/pisensor/scripts/dht22_mqtt.py & 重新启动后,mqtt 服务器上的预期消息没有出现,所以我在控制台上尝试 运行ning 脚本。我在目录中用 python3 dht22_mqtt.py 调用它,几秒钟后它看起来像是完成了(控制台中的新行),但什么也没做(没有消息到 mqtt 服务器,也没有打印消息).没有显示库丢失或出现问题的错误。 运行从控制台使用这样的异步脚本会不会有问题?

当从控制台 运行 时是否可以调试脚本?我试了python3的-d参数,结果一样。 我用 dht 和 paho-mqtt 库尝试了 pip3,但它已经安装了。

您可以在这里查看脚本:

from time import sleep
import asyncio
from paho.mqtt import subscribe, publish
from random import randint
from typing import Awaitable, Any


async def run_sequence(*functions: Awaitable[Any]) -> None:
    for function in functions:
        await function


async def run_parallel(*functions: Awaitable[Any]) -> None:
    await asyncio.gather(*functions)


class IOTSensorDHT22:

    def __init__(self,
                 mqtt_server="localhost",
                 mqtt_port=1883,
                 sensor_pin=4,
                 sensor_values_topic_prefix="/sensor/raw/bedroom/",
                 sensor_interval=60,
                 sensor_interval_topic="/setting/sensor/inside/power/interval"):
        self.messages = None
        self.values = None
        self.mqtt_server = mqtt_server
        self.mqtt_port = mqtt_port
        self.sensor_pin = sensor_pin
        self.sensor_values_topic_prefix = sensor_values_topic_prefix
        self.sensor_interval = sensor_interval
        self.sensor_interval_topic = sensor_interval_topic
        self.mqtt_client_id = f"mqtt_client_{randint(0, 1000)}"

    async def query_interval(self):
        new_interval = int(subscribe.simple(self.sensor_interval_topic, hostname=self.mqtt_server).payload)
        if new_interval != self.sensor_interval:
            print(
                f"new interval {new_interval} - old: {self.sensor_interval} - assigning new value: {new_interval != self.sensor_interval}")
            self.sensor_interval = new_interval

    async def publish_values(self):
        print(f"publishing messages: {self.messages}")
        publish.multiple(self.messages, hostname=self.mqtt_server)

    async def measure(self):
        self.values = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, self.sensor_pin)

    async def build_messages(self):
        messages = (self.build_message("hum", self.values[0]), self.build_message("temp", self.values[1]))
        print(messages)
        self.messages = messages

    def build_message(self, topic_appendix, value):
        return self.sensor_values_topic_prefix + topic_appendix, round(value, 1)

    def sleep(self):
        print(f"going to sleep for {self.sensor_interval}")
        sleep(self.sensor_interval)

    async def run(self):
        while True:
            await run_parallel(
                run_sequence(self.measure(), self.build_messages(), self.publish_values()),
                self.query_interval()
            )
            self.sleep()


if __name__ is "__main__":
    asyncio.run(
        IOTSensorDHT22(
            mqtt_server="192.168.188.37",  #
            sensor_pin=12,
            sensor_values_topic_prefix="/sensor/raw/bedroom/",
            sensor_interval=60,
            sensor_interval_topic="/setting/sensor/inside/power/interval/").run())

编辑:感谢编辑帮助:)

更新 - 已解决:

我写了if __name__ is "__main__":

本来应该是

if __name__ == "__main__":

这确实是我的错误,但它误导了我,它在 IDE (Thonny) 中运行良好,但在 运行 从控制台运行时什么也没做。

您可以使用 ipdb 在控制台中进行调试。

pip install ipdb

然后将其放入您的代码中您要调试的位置:

import ipdb
ipdb.set_trace()

然后您就可以单步执行您的代码,就像使用来自 IDE 的调试器一样。有关如何使用 ipdb 的更多说明,请参阅 this tutorial.