在python 3中子类化文件对象(以扩展打开和关闭操作) [英] subclassing file objects (to extend open and close operations) in python 3
问题描述
假设我想在 open
和 close
时间使用额外的操作来扩展内置文件抽象.在 Python 2.7 中,这有效:
class ExtFile(file):def __init__(self, *args):file.__init__(self, *args)# 额外的东西在这里定义关闭(自我):file.close(self)# 额外的东西在这里
现在我正在考虑将程序更新到 Python 3,其中 open
是一个工厂函数,它可以从 io
模块取决于它的调用方式.原则上我可以将所有这些子类化,但这很乏味,而且我必须重新实现 open
所做的分派.(在 Python 3 中,二进制文件和文本文件之间的区别比在 2.x 中更重要,我需要两者.)这些对象将被传递给可能对它们做任何事情的库代码,所以习惯用法制作一个类似文件"的鸭子类型的类来包装 open
的返回值并转发必要的方法将是最冗长的.
谁能建议一种 3.x 方法,在显示的 2.x 代码之外尽可能少地涉及额外的样板?
您可以只使用上下文管理器.例如这个:
class SpecialFileOpener:def __init__ (self, fileName, someOtherParameter):self.f = 打开(文件名)# 做更多的事情打印(一些其他参数)def __enter__ (self):返回 self.fdef __exit__ (self, exc_type, exc_value, traceback):self.f.close()# 做更多的事情print('一切都结束了.')
然后你可以这样使用它:
<预><代码>>>>with SpecialFileOpener('C:\\test.txt', 'Hello world!') as f:打印(f.read())你好,世界!富吧全都结束了.无论如何,对于文件对象(和其他资源),首选使用带有 with
的上下文块.
Suppose I want to extend the built-in file abstraction with extra operations at open
and close
time. In Python 2.7 this works:
class ExtFile(file):
def __init__(self, *args):
file.__init__(self, *args)
# extra stuff here
def close(self):
file.close(self)
# extra stuff here
Now I'm looking at updating the program to Python 3, in which open
is a factory function that might return an instance of any of several different classes from the io
module depending on how it's called. I could in principle subclass all of them, but that's tedious, and I'd have to reimplement the dispatching that open
does. (In Python 3 the distinction between binary and text files matters rather more than it does in 2.x, and I need both.) These objects are going to be passed to library code that might do just about anything with them, so the idiom of making a "file-like" duck-typed class that wraps the return value of open
and forwards necessary methods will be most verbose.
Can anyone suggest a 3.x approach that involves as little additional boilerplate as possible beyond the 2.x code shown?
You could just use a context manager instead. For example this one:
class SpecialFileOpener:
def __init__ (self, fileName, someOtherParameter):
self.f = open(fileName)
# do more stuff
print(someOtherParameter)
def __enter__ (self):
return self.f
def __exit__ (self, exc_type, exc_value, traceback):
self.f.close()
# do more stuff
print('Everything is over.')
Then you can use it like this:
>>> with SpecialFileOpener('C:\\test.txt', 'Hello world!') as f:
print(f.read())
Hello world!
foo bar
Everything is over.
Using a context block with with
is preferred for file objects (and other resources) anyway.
这篇关于在python 3中子类化文件对象(以扩展打开和关闭操作)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!