我需要一个装饰器(或任何其他整洁的设计模式)来处理文件。主要目的是在函数作用于文件之后将文件指针保持在它所在的相同位置。
这是我的代码,包括一些虚拟测试。问题是装饰器不适用于实例方法,即使我将args
和kwargs
传递给它。我无法弄清楚如何设计代码...
import unittest
from cStringIO import StringIO
def remain_file_pointer(file_obj):
def wrap(f):
def wrapped_f(*args, **kwargs):
old_position = file_obj.tell()
f(*args, **kwargs)
file_obj.seek(old_position, 0)
return wrapped_f
return wrap
class TestRemainFilepointer(unittest.TestCase):
def test_remains_filepointer(self):
dummy_file = StringIO('abcdefg')
@remain_file_pointer(dummy_file)
def seek_into_file(dummy_file):
dummy_file.seek(1, 0)
self.assertEqual(0, dummy_file.tell())
seek_into_file(dummy_file)
self.assertEqual(0, dummy_file.tell())
def test_remains_filepointer_in_class_method(self):
class FileSeekerClass(object):
def __init__(self):
self.dummy_file = StringIO('abcdefg')
@remain_file_pointer(self.dummy_file)
def seek_into_file(self):
self.dummy_file.seek(1, 0)
fileseeker = FileSeekerClass()
self.assertEqual(0, fileseeker.dummy_file.tell())
fileseeker.seek_into_file()
self.assertEqual(0, fileseeker.dummy_file.tell())
更新 只是为了澄清基本想法:
装饰器应该接受一个参数,它是一个文件处理程序并在实际函数操作文件之前存储位置。之后,指针应设置为旧位置。这应该适用于独立功能和方法。
我的回答通过假设函数中的最后一个参数是文件处理程序来解决问题。
答案 0 :(得分:0)
我不会将此标记为最终答案,因为我非常确定有更好的设计。
我提出了一个解决方案,假设数据操作函数的最后一个参数是文件处理程序并通过args[-1]
访问它:
def remain_file_pointer(f):
"""Remain the file pointer position after calling the decorated function
This decorator assumes that the last argument is the file handler.
"""
def wrapper(*args, **kwargs):
file_obj = args[-1]
old_position = file_obj.tell()
return_value = f(*args, **kwargs)
file_obj.seek(old_position, 0)
return return_value
return wrapper