【发布时间】:2020-11-25 13:51:25
【问题描述】:
我正在使用 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()。当您创建 newapp 而不调用 app.close() 时会发生什么没有明确定义。我不确定 C# 将如何处理这个问题,它会覆盖内存中的app,app 现在还会指向newapp,还是其他什么?有了这个,我就更不确定python+CLR是怎么处理的了。
为了确保您始终使用正确连接的应用程序,我创建了一个类,它只允许存在一个 app 实例。此限制是通过 API 评估 connection.Alive 来实现的,当应用程序已生成但尚未正确关闭时,该限制为 True。该类类似于:
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。另外,我只是想知道是否有适当的方法来处理这些最终确定问题?
【问题讨论】:
标签: python c# api code-cleanup python.net