在为自己的类使用with语句时需要注意哪些事项?

时间:2012-01-18 10:58:39

标签: python with-statement

我打算使用方便的with语句为我的一个Python类实现类似C ++的构造函数/析构函数。到目前为止,我只是针对文件IO来讨论此声明,但我认为这对基于连接的通信任务也很有用,比如说socketsdatabase connections。最终需要关闭的事情。

在PEP 343(上面已链接)中,with需要方法__enter____exit__,而我的直接实现似乎按预期工作。< / p>

class MyConnection:
  def __init__(self):
    pass
  def __enter__(self):
    print "constructor"
    # TODO: open connections and stuff
    # make the connection available in the with-block
    return self 
  def __exit__(self, *args):
    print "destructor"
    # TODO: close connections and stuff

with MyConnection() as c:
  # TODO: do something with c
  pass

产生输出(如预期的那样):

constructor
destructor

这真的很容易吗?除此之外还有什么要考虑的事情?为什么这么多库(显然)缺少这个功能呢?我错过了什么吗?

2 个答案:

答案 0 :(得分:5)

(a)就这么简单

(b)另一种方法是装饰器函数,它修饰函数(和类,但不包括此用例),并且还允许在包装函数之前和之后调用代码。这些似乎更常见。

(c)我认为你没有遗漏任何东西。

答案 1 :(得分:0)

尝试在我的库中实现“with”功能时遇到的一个问题是找出处理故障异常的优雅方法。鉴于以下内容:

class open_file_for_read(object):
    def __init__(self):
        self.filename = "./does_not_exist.txt"
        self.fileobj = None

    def __enter__(self):
        print("Opening file %s for read" % self.filename)
        self.fileobj = open(name=self.filename, mode='r')
        return self.fileobj

    def __exit__(self, type, value, traceback):
        self.fileobj.close()


with open_file_for_read() as fh:
    for li in fh.readlines():
        print(li)

处理不可避免的“IOError:[Errno 2]没有这样的文件或目录的推荐方法是什么:'。/ does_not_exist.txt'”异常?始终存在'尝试/除外'方法

try:
    with open_file_for_read() as fh:
except IOError:
    ...
except XXX:
    ...
...

这种直接方法有效,但我认为这有损于使用'with'结构的简单性。也许有人在那里有一个更优雅的解决方案?

这对于这个问题更多的是问题而不是答案,但这是我在尝试实施'with'时遇到的问题之一。