5

我喜欢使用 with 语句来访问文件和数据库连接,因为如果发生错误或文件关闭,它会自动为我断开连接。

f = open('file.txt', 'r')
for i in f():
   print(i)
f.close()

相对

with open('file.txt', 'r') as f:
   for i in f:
       print(i)

以下是否有从相机缓冲区读取的等效改写?:

c = cv.VideoCapture(0)    
while(1):
    _,f = c.read()
    cv.imshow('e2',f)
    if cv.waitKey(5)==27:
        cv.waitKey()
        break
c.release()

我试过了:

c = cv.VideoCapture(0)    
while(1):
   with c.read() as _,f:
       cv.imshow('e2',f)
       if cv.waitKey(5)==27:
           cv.waitKey()
           break

---没有运气。看起来拆卸/释放是一种不同的功能。这个成语在这里可以吗?

4

2 回答 2

8

其他方式:

from contextlib import contextmanager

@contextmanager
def VideoCapture(*args, **kwargs):
    cap = cv2.VideoCapture(*args, **kwargs)
    try:
        yield cap
    finally:
        cap.release()
于 2016-01-08T15:27:08.290 回答
7

我不知道opencv,所以可能有更好的答案——但你总是可以通过定义和钩子自己实现上下文管理器:__enter____exit__

class MyVideoCapture(cv.VideoCapture):
    def __enter__(self):
        return self
    def __exit__(self, *args):
        self.release()

用法将如下所示:

with MyVideoCapture(0) as c:    
    while(True):
        _, f = c.read()
        cv.imshow('e2', f)
        if cv.waitKey(5) == 27:
            cv.waitKey()
            break

break并且在您点击语句后资源将被释放。

根据您的评论,看起来opencv这里正在做一些时髦的事情。您还可以创建一个自定义类来包装 VideoCapture 实例。在当今世界,我可能会使用contextlib

@contextlib.contextmanager
def video_capture_wrapper(*args, **kwargs):
    try:
        vid_stream = VideoCapture(*args, **kwargs)
        yield vid_stream
    finally:
         vid_stream.release()

这里的用法是:

with video_capture_wrapper(0) as vid_stream:    
    while(True):
        _, f = vid_stream.read()
        cv.imshow('e2', f)
        if cv.waitKey(5) == 27:
            cv.waitKey()
            break
于 2013-09-30T04:32:58.150 回答