如何在Python中重写PySerial的"__del__"方法?

1 投票
2 回答
2664 浏览
提问于 2025-04-16 16:23

我有一个简单的Python脚本,用来向一个连接在COM3端口的设备发送字符。
(这个脚本是在Windows XP上运行的)
设备可以正常接收到字符,但当脚本结束,或者我调用

ser.close()      #ser is an instance of the `serial` method `Serial`

时,它会把串口上的DTR线设置为高电平,这样就会重置我的设备。

对此我感到很困惑,于是我在PySerial的文档里查了一下(http://pyserial.sourceforge.net/),发现这个模块有一个叫做__del__的方法,当串口实例被删除时,它会调用ser.close()函数。

请问有没有办法重写这个__del__方法呢?

(我希望不必把设备的重置线从DTR线上拔掉)

下面是我正在使用的基本代码:

import serial
ser = serial.Serial()
ser.port = 2      #actually COM3
ser.baudrate = 9600
ser.open()
ser.write("Hello")
ser.close()

2 个回答

2

你试过像这样做吗?

MySerial = serial.Serial

def dummy_del(obj):
    pass

MySerial.__del__ = dummy_del

ser = MySerial()
3

当然,可以去重写这个方法。你可以创建一个叫做 Serial 的子类,并在里面指定一个什么都不做的 __del__() 方法,然后用这个子类来代替 Serial。另外一种方法是直接从原来的 Serial 类中删除这个方法(这叫做猴子补丁),可以用 del 语句来实现。第一种方法更好,但如果有些你无法控制的代码在使用串口,第二种方法可能就需要了。当然,在重写之前,确保 __del__() 方法里面没有其他重要的操作。

子类化:

import serial

class mySerial(serial.Serial):
    def __del__(self):
        pass

ser = mySerial()
# rest of script the same

猴子补丁:

import serial

del serial.Serial.__del__

如果你有这个模块的Python源代码(也就是说,它不是用C写的),还有一种方法是自己复制一份,然后直接编辑它,让它不执行那个操作。(对于C模块也是可以这样做的,但如果你没有C语言的专业知识,运行起来会有点困难。)

当然,把 __del__() 方法改成不调用 ser.close() 对你给出的代码帮助不大,因为你自己已经在调用 ser.close() 了。:-)

撰写回答