如何为类提供类似 with 语句的功能?
[我对这个不恰当的标题表示歉意;我想不出更好的办法了。欢迎提出更好标题的建议。]
我想实现一个支持多进程的 HDF5 文件的接口 -通过文件锁定级别并发。该模块的预期环境是通过 NFS 访问共享磁盘的 Linux 集群。目标是通过在多个不同主机上运行的多个并行进程实现对同一文件的并发访问(通过 NFS)。
我希望能够通过 h5py.File
类的包装类来实现锁定功能。 (h5py
已提供对线程的支持 级并发,但底层 HDF5 库不是线程安全的。)
如果我能本着这个精神做一些事情,那就太好了:
class LockedH5File(object):
def __init__(self, path, ...):
...
with h5py.File(path, 'r+') as h5handle:
fcntl.flock(fcntl.LOCK_EX)
yield h5handle
# (method returns)
我意识到上面的代码是错误的,但我希望它传达了主要思想:即有这样的表达LockedH5File('/path/to/file')
向客户端代码传递一个打开句柄,然后客户端代码可以对其执行各种任意读/写操作。当该句柄超出范围时,其析构函数将关闭该句柄,从而释放锁。
推动这种安排的目标有两个:
将句柄的创建(由库代码)与随后在句柄上请求的操作(由客户端代码)分离,
确保句柄是关闭并释放锁,无论期间发生什么 执行中间代码(例如异常、未处理的 信号,Python 内部错误)。
在Python中怎样才能达到这样的效果呢?
谢谢!
[I apologize for the inept title; I could not come up with anything better. Suggestions for a better title are welcome.]
I want to implement an interface to HDF5 files that supports multiprocess-level concurrency through file-locking. The intended environment for this module is a Linux cluster accessing a shared disk over NFS. The goal is to enable the concurrent access (over NFS) to the same file by multiple parallel processes running on several different hosts.
I would like to be able to implement the locking functionality through a wrapper class for the h5py.File
class. (h5py
already offers support for thread-level concurrency, but the underlying HDF5 library is not thread-safe.)
It would be great if I could do something in the spirit of this:
class LockedH5File(object):
def __init__(self, path, ...):
...
with h5py.File(path, 'r+') as h5handle:
fcntl.flock(fcntl.LOCK_EX)
yield h5handle
# (method returns)
I realize that the above code is wrong, but I hope it conveys the main idea: namely, to have the expression LockedH5File('/path/to/file')
deliver an open handle to the client code, which can then perform various arbitrary read/write operations on it. When this handle goes out of scope, its destructor closes the handle, thereby releasing the lock.
The goal that motivates this arrangement is two-fold:
decouple the creation of the handle (by the library code) from the operations that are subsequently requested on the handle (by the client code), and
ensure that the handle is closed and the lock released, no matter what happens during the
execution of the intervening code (e.g. exceptions, unhandled
signals, Python internal errors).
How can I achieve this effect in Python?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
可以在
with
语句中使用的对象称为上下文管理器;他们实现了一个简单的界面。它们必须提供两个方法,一个__enter__
方法,该方法不带任何参数,并且可以返回任何内容(将被分配给as
部分中的变量),以及一个>__exit__
方法,它接受三个参数(将用 sys.exc_info() 的结果填充)并返回非零以指示异常已被处理。您的示例可能如下所示:objects that can be used in
with
statements are called context managers; and they implement a simple interface. They must provide two methods, an__enter__
method, which takes no arguments and may return anything (which will be assigned to the variable in theas
portion), and an__exit__
method, which takes three arguments (which will be filled in with the result ofsys.exc_info()
) and returns non-zero to indicate that an exception was handled. Your example will probably look like:要实现此功能,您的类需要实现上下文管理器协议。或者,使用
contextlib.contextmanager
装饰器编写生成器函数。您的类可能大致如下所示(
h5py
用法的详细信息可能是严重错误的):To make this work, your class needs to implement the context manager protocol. Alternatively, write a generator function using the
contextlib.contextmanager
decorator.Your class might roughly look like this (the details of
h5py
usage are probably horribly wrong):嗯,一个上下文管理器和
with
语句。一般来说,Python 中的析构函数根本不能保证运行,因此除了故障安全清理之外,您不应该依赖它们。提供__enter__
和__exit__
方法,并像使用它一样Well, a context manager and
with
statement. In general, destructors in Python are not guaranteed to run at all, so you should not rely on them as anything other than fail-safe cleanup. Provide__enter__
and__exit__
methods, and use it like