我正在使用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将如何处理这个问题,它会覆盖内存中的app
吗app
现在还会指向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。此外,我只是想知道是否有一个适当的方式来处理这些最终确定的问题
首先,如果调用
wrap.connect()
而不将返回值存储在任何地方是一个问题,那么有一个简单的解决方案:不要这样做!看起来连接是一种资源,因此您必须跟踪它,以便在适当的时候释放它在您的示例中,当有人再次调用
connect()
时,先前创建的连接会发生什么情况其次,在Python中,有两种方法可以显式跟踪资源:
__del__
函数,您可以定义,当不再需要对象时将调用该函数。您应该避免这种情况,因为它将在任意时间执行,这意味着当您尝试创建新连接时,旧连接可能仍然存在,因为Python还没有意识到它应该调用__del__
李>另一种选择是制作a singleton
相关问题 更多 >
编程相关推荐