而不诉诸''.join,有没有使用PyYAML的一个Python化的方式yaml.load_all与fileinput.input()来自多个源的多个文件容易流?
我正在寻找类似以下的内容(非工作示例):
# example.py
import fileinput
import yaml
for doc in yaml.load_all(fileinput.input()):
print(doc)
Run Code Online (Sandbox Code Playgroud)
预期输出:
$ cat >pre.yaml <<<'--- prefix-doc'
$ cat >post.yaml <<<'--- postfix-doc'
$ python example.py pre.yaml - post.yaml <<<'--- hello'
prefix-doc
hello
postfix-doc
Run Code Online (Sandbox Code Playgroud)
当然,yaml.load_all需要字符串、字节或类似文件的对象,fileinput.input()而这些都不是,因此上面的示例不起作用。
实际输出:
$ python example.py pre.yaml - post.yaml <<<'--- hello'
...
AttributeError: FileInput instance has no attribute 'read'
Run Code Online (Sandbox Code Playgroud)
您可以使示例与 一起使用''.join,但这是作弊。我正在寻找一种不会一次将整个流读入内存的方法。
我们可以将问题重新表述为是否有某种方法可以模拟字符串、字节或类似文件的对象来代理字符串的底层迭代器?但是,我怀疑这是否yaml.load_all真的需要整个类似文件的界面,因此措辞会要求比严格必要的更多。
理想情况下,我正在寻找支持以下内容的最小适配器:
for doc in yaml.load_all(minimal_adapter(fileinput.input())):
print(doc)
Run Code Online (Sandbox Code Playgroud)
问题fileinput.input在于生成的对象没有read方法,这就是yaml.load_all正在寻找的方法。如果你愿意放弃fileinput,你可以编写自己的类来做你想做的事:
import sys
import yaml
class BunchOFiles (object):
def __init__(self, *files):
self.files = files
self.fditer = self._fditer()
self.fd = self.fditer.next()
def _fditer(self):
for fn in self.files:
with sys.stdin if fn == '-' else open(fn, 'r') as fd:
yield fd
def read(self, size=-1):
while True:
data = self.fd.read(size)
if data:
break
else:
try:
self.fd = self.fditer.next()
except StopIteration:
self.fd = None
break
return data
bunch = BunchOFiles(*sys.argv[1:])
for doc in yaml.load_all(bunch):
print doc
Run Code Online (Sandbox Code Playgroud)
本BunchOFiles类让你的对象具有read将愉快地叠代的文件列表,直到一切都用尽方法。鉴于上面的代码和您的示例输入,我们得到了您正在寻找的输出。
| 归档时间: |
|
| 查看次数: |
669 次 |
| 最近记录: |