如果在 __init__ 中未使用,则类 ser 端口为无

Posted

技术标签:

【中文标题】如果在 __init__ 中未使用,则类 ser 端口为无【英文标题】:Class ser port is none if unused in __init__ 【发布时间】:2020-04-02 21:41:59 【问题描述】:

我正在编写一个使用函数 get_serial_port() 的类。如果在 init 中没有调用 self.ser.write('at\r'),那么 self.ser 在类的其他地方是 None 。 (注意 get_serial_port 函数在返回实例之前验证通信)。我认为这与 Serial 类中的垃圾收集有关,但我不明白发生了什么。这是为什么呢?

函数 get_serial_port 检查通信并返回链接到 com 端口的实例。 init_module() 函数使用 self.ser.write('command') 运行多个函数。它按原样工作,但我不喜欢有我不理解的代码......

class Device():
    def __init__(self, log = True, com_port=None, imei=None, ser=None, baud_rate=115200):
        if log:
            self.log = True
            self.log = Logger()
            self.log.start_log()
        if ser is None:
            try: 
                self.ser = get_serial_port(baud_rate=baud_rate)
                self.ser.write('at\r')
                print(self.ser.read(1000))
            except:
                print('ERROR: serial port connection failed')
            else:
                self.ser = ser
        self.imei = imei
        self.init_module()

【问题讨论】:

【参考方案1】:

代码中存在一些问题。一方面,将 log 设置为 True 不会做任何事情,因为相同的实例 var 在同一行中被覆盖。我不是说这是模范,但这会更清楚一点吗?我试图重写它以便更容易跟踪状态。

还添加了一些惯用的约定(除非确实需要,否则不要显式测试 None)

class Device():
    def __init__(self, log = True, com_port=None, imei=None, ser=None, baud_rate=115200):
        self.log_enabled = log
        self.ser = ser
        self.imei = imei

        if log:
            self.logger = Logger()
            self.logger.start_log()

        if not self.ser:
            try: 
                self.ser = get_serial_port(baud_rate=baud_rate)
                self.ser.write('at\r')
                print(self.ser.read(1000))
            except:
                print('ERROR: serial port connection failed')

        self.init_module()

请注意,我将 log 布尔值单独存储到 self.log_enabled 中,以便在启用日志记录的情况下可以在代码中对其进行检查。不过还有更好的选择:

在运行时设置日志级别,而不是禁用日志记录,将其设置为 warning 或类似以仅记录重要的事情 你也可以创建另一个Null logger,其接口类似于Logger(),这样就不需要每次都使用if了

但我会使用日志级别,然后您可以删除第一个 if -- 删除条件通常是简化代码的好方法 -- 并且只需使用日志级别。

【讨论】:

以上是关于如果在 __init__ 中未使用,则类 ser 端口为无的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在不使用 __init__ 的情况下在实例初始化时自动运行方法?

Cython __pyx_r 可能在此函数中未初始化使用

[python][转载]__init__.py使用

__init__() 在 Python 2 中使用 argparse 得到了一个意外的关键字参数“必需”[重复]

如何在(子)模块中使用 __init__.py 来定义命名空间?

从查询到子查询的组中未选择的值