如何正确完成/清理pythonnet CLR对象?

2024-09-27 07:18:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用python通过提供的API与某个软件进行通信。由于API代码是用C#编写的,所以我使用pythonnet导入DLL并随后使用它。在优化代码时,使用Jupyter Lab或Jupyter Notebook这样做是有益的,因为您可以轻松比较代码和软件中的结果。但是,我遇到了清理问题。API要求您通过运行以下代码来建立连接

import clr
clr.AddReference('API')
api = __import__('API', globals(), locals(), [], 0)
connection = api.connection()
app = connection.connect()

现在,您可以使用app与软件通信。我发布此问题的主要原因是,CLR中只允许有一个应用程序。如果您想创建一个新的,您应该调用app.close(),然后调用newapp = connection.connect()。当您在不调用app.close()的情况下创建newapp时会发生什么情况还没有明确定义。我不确定C将如何处理这个问题,它会覆盖内存中的appapp现在还会指向newapp还是其他什么?因此,我更不确定python+CLR是如何处理它的

为了确保您的应用程序始终与正确连接的应用程序一起工作,我创建了一个类,该类只允许存在一个app实例。这个限制是通过通过API计算connection.Alive来实现的,当一个应用程序已经生成并且还没有正确关闭时,这是正确的。该类类似于:

class APIWrapper:
    def __init__(self, api):
        self.API = api
        self.Connection = api.connection()
   
    def connect():
        if self.Connection.Alive:
            raise RunTimeError('Only one live application is allowed at runtime')

        app = self.Connection.connect()
        return app

虽然这很好,但当我意外地做了以下事情时,我的问题就会出现:

wrap = APIWrapper()
wrap.connect()

执行此操作时,应用程序将启动,wrap.Connection.Alive的计算结果为True。但是,由于我没有将wrap.connect()的返回赋值给变量,因此无法使用app.close()关闭它。例如,如果我这样做:

wrap = APIWrapper()
print(wrap.Connection.Alive)  # -> False
app = wrap.connect()
print(wrap.Connection.Alive)  # -> True
app.close()
print(wrap.Connection.Alive)  # -> False
wrap.connect()
print(wrap.Connection.Alive)  # -> True

我不能再关闭连接了。我已经考虑过修改这个类,以便将wrap.connect()绑定到wrap.App并允许通过属性进行访问。这将解决丢失应用程序的问题,但我不希望为了代码可读性而不断调用wrap.app。此外,我只是想知道是否有一个适当的方式来处理这些最终确定的问题


Tags: 代码selfapiapp应用程序close软件connect
1条回答
网友
1楼 · 发布于 2024-09-27 07:18:51

首先,如果调用wrap.connect()而不将返回值存储在任何地方是一个问题,那么有一个简单的解决方案:不要这样做!看起来连接是一种资源,因此您必须跟踪它,以便在适当的时候释放它

在您的示例中,当有人再次调用connect()时,先前创建的连接会发生什么情况

其次,在Python中,有两种方法可以显式跟踪资源:

  1. ^{} statements + context managers(强烈建议)。在这种情况下,您需要在包装器上实现一个上下文管理器
  2. __del__函数,您可以定义,当不再需要对象时将调用该函数。您应该避免这种情况,因为它将在任意时间执行,这意味着当您尝试创建新连接时,旧连接可能仍然存在,因为Python还没有意识到它应该调用__del__

另一种选择是制作a singleton

相关问题 更多 >

    热门问题