gpt4 book ai didi

python - Python 模块中的全局状态

转载 作者:太空狗 更新时间:2023-10-30 00:07:39 27 4
gpt4 key购买 nike

我正在使用 cffi 为 C 库编写 Python 包装器。

C 库必须初始化并关闭。此外,cffi 需要一些地方来保存从 ffi.dlopen() 返回的状态。

我可以在这里看到两条路径:

要么我将整个有状态的业务包装在这样的类中

class wrapper(object):
def __init__(self):
self.c = ffi.dlopen("mylibrary")
self.c.initialize()
def __del__(self):
self.c.terminate()

或者我提供两个将状态隐藏在全局变量中的全局函数

def initialize():
global __library
__library = ffi.dlopen("mylibrary")
__library.initialize()
def terminate():
__library.terminate()
del __library

第一个路径有点麻烦,因为它要求用户始终创建一个对象,该对象除了管理库状态外没有其他用途。另一方面,它确保 terminate() 实际上每次都被调用。

第二条路径似乎导致 API 更简单一些。然而,它暴露了一些隐藏的全局状态,这可能是一件坏事。此外,如果用户忘记调用 terminate(),则 C 库无法正确卸载(这在 C 端不是大问题)。

这些路径中的哪一个会更 pythonic?

最佳答案

只有当库实际上支持一个应用程序中的多个实例时,才在 python 中公开包装器对象才有意义。如果它不支持它或者它不是真正相关的,请听取 kindall 的建议,并在导入时初始化库并添加一个 atexit 处理程序以进行清理。

在无状态 api 周围添加包装器,甚至在不支持保持不同状态集的 api 周围添加包装器并不是真正的 pythonic,并且会提高对不同实例具有某种隔离的期望。

示例代码:

import atexit

# Normal library initialization
__library = ffi.dlopen("mylibrary")
__library.initialize()

# Private library cleanup function
def __terminate():
__library.terminate()
# register function to be called on clean interpreter termination
atexit.register(__terminate)

有关 atexit 的更多详细信息 this question有更多详细信息,python documentation 也有当然。

关于python - Python 模块中的全局状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17346428/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com