我正在研究测试一些作用在文件上的代码的方法,但是我想编写一些测试,这些测试仅依赖于源文件中的特定字符串,而不是在文件系统中的某个位置具有特定的文件。
我知道可以file
通过向字符串提供类似的流接口io.StringIO
。
问题在于操作不遵循相同的语义。例如,根据文件对象是来自还是来自包含非ASCII字符的字符串,组合file.seek()
和file.read()
将产生不同的结果:open()
io.StringIO
import io
# 'abgdezhjiklmnxoprstufqyw'
text = '??????????????o?????????'
with open('test.txt', 'w') as file_obj:
file_obj.write(text)
with open('test.txt', 'r') as file_obj:
file_obj.seek(8)
print(file_obj.read(8))
# ????????
with io.StringIO(text) as file_obj:
file_obj.seek(8)
print(file_obj.read(8))
# ??????o?
Run Code Online (Sandbox Code Playgroud)
仅纯ASCII的字符串不会出现此问题:
import io
text = 'abgdezhjiklmnxoprstufqyw'
with open('test.txt', 'w') as file_obj:
file_obj.write(text)
with open('test.txt', 'r') as file_obj:
file_obj.seek(8)
print(file_obj.read(8))
# iklmnxop
with io.StringIO(text) as file_obj:
file_obj.seek(8)
print(file_obj.read(8))
# iklmnxop
Run Code Online (Sandbox Code Playgroud)
显然,这是由于.seek()
以下一个bytes
语义为offset
在打开的文件的情况下参数open()
,而io.StringIO
它遵循str
的语义。
我确实了解,出于性能原因,即使文件以文本模式打开,具有seek()
以下str
语义也不可行。
因此,我的问题是:如何获得符合语义io.StringIO()
的seek
方法的等效项bytes
?我需要超越io.StringIO
自己还是有更好的方法?
您可以使用BytesIO
和TextIOWrapper
来模拟真实文件的行为:
text = '??????????????o?????????'
with io.BytesIO(text.encode('utf8')) as binary_file:
with io.TextIOWrapper(binary_file, encoding='utf8') as file_obj:
file_obj.seek(8)
print(file_obj.read(8))
# ????????
Run Code Online (Sandbox Code Playgroud)