在 __del__ 中关闭类似连接的对象的 Pythonic 方法

cel*_*cel 4 python

我正在研究一个实现上下文管理器的类似连接的对象。强烈鼓励写这样的东西:

with MyConnection() as con:
    # do stuff
Run Code Online (Sandbox Code Playgroud)

当然也可以这样做:

con = MyConnection()
# do stuff
con.close()
Run Code Online (Sandbox Code Playgroud)

但未能关闭连接是相当有问题的。所以关闭__del__()似乎是一个好主意:

def __del__(self):
    self.close()
Run Code Online (Sandbox Code Playgroud)

这看起来很不错,但有时会导致错误:

Exception ignored in: [...]
Traceback (most recent call last):
  File "...", line xxx, in __del__()
TypeError: 'NoneType' object is not callable
Run Code Online (Sandbox Code Playgroud)

看起来好像有时 close 方法已经被销毁,当__del__()被调用时。

所以我正在寻找一种很好的方法来鼓励 python 在破坏时正确关闭连接。如果可能的话,我想,以避免代码重复close()__del__()

Séb*_*rez 9

如果你真的想阻止用户不关闭连接,你可以只初始化它,__enter__或者你可以添加一个标志来发现它没有被上下文管理器初始化。例如,像

class MyConnection(object):

    safely_initialized = False

    def __enter__(self):
        # Init your connection
        self.safely_initialized = True
        return self

    def do_something(self):
        if not self.safely_initialized:
            raise Exception('You must initialize the connection with a context manager!')
        # Do something

    def __exit__(self, type, value, traceback):
        # Close your connection
Run Code Online (Sandbox Code Playgroud)

这样除非在上下文管理器中,否则连接不会被初始化。