我正在尝试自定义用于url = 'https://bing.com' + url
和python 2.7
(至少python 3.x
)的库中文件句柄的行为。
我正在实现的自定义行为要求在调用>=3.6
方法时必须执行某些操作,无论是直接(close
)还是fh.close()
方法的结果。
我也在尝试添加其他方法-叫它__exit__()
。
我的理想世界是为用户提供一个可以正常使用的文件句柄(读/读线/写/ ...),但在幕后还要有一些特殊的逻辑。
这是我目前正在使用的东西...
custom_copy()
以上代码在from os import fsync
def custom_open(filepath, mode='rt', *args **kwargs):
# Open the file normally using open_args
orig_file_handle = open(filepath, mode, *args, **kwargs) # pylint: disable=star-args
# Preserve original close function
original_close_fn = orig_file_handle.close
# Create a custom close function
def custom_close_fn(*args, **kwargs):
original_close_fn(*args, **kwargs)
print("Do Something Custom")
orig_file_handle.close = custom_close_fn
# Add custom_copy function
def custom_copy_fn(*args, **kwargs):
if orig_file_handle.closed:
raise ValueError("I/O operation on closed file")
# Ensure buffer has been flushed before rsync
orig_file_handle.flush()
fsync()
return _my_custom_copy(filepath, *args, **kwargs)
orig_file_handle.custom_copy = custom_copy_fn
return orig_file_handle
中有效,但是在python3.7.0
中却失败了
python2.7.8
我还尝试了另一种涉及子类化> orig_file_handle.close = custom_close_fn
E AttributeError: 'file' object attribute 'close' is read-only
的方法,但是还有其他一些问题...
type(orig_file_handle)
在def custom_open(filepath, mode='rt', open_args=None):
open_args = open_args or {}
open_args['mode'] = mode
# Open the file normally using open_args
orig_file_handle = open(filepath, **open_args) # pylint: disable=star-args
class CustomFile(type(orig_file_handle)):
def __init__(self, file_handle):
# pylint: disable=super-init-not-called
self.__dict__ = file_handle.__dict__.copy()
def close(self, *args, **kwargs):
# Execute normal file handle close
super(CustomFile, self).close(*args, **kwargs)
print("Do Something Custom")
def custom_copy(self, *args, **kwargs):
if self.closed: # pylint: disable=no-member
raise ValueError("I/O operation on closed file")
self.flush() # pylint: disable=no-member
fsync()
return _my_custom_copy(filepath, *args, **kwargs)
return CustomFile(orig_file_handle)
中,此失败并显示
python2.7.8
在> self.__dict__ = file_handle.__dict__.copy()
E AttributeError: 'file' object has no attribute '__dict__'
中,它失败并
python3.7.0
有什么想法可以解决此问题,或者我应该遵循其他模式才能获得想要的结果吗?
一吨!
答案 0 :(得分:0)
请勿继承,修饰:
class CustomFile:
def __init__(self, file_handle):
# pylint: disable=super-init-not-called
self._f = file_handle
def close(self, *args, **kwargs):
self._f.close(*args,**kwargs)
print("Do Something Custom")
self.closed = True
编辑
This recipe关于代理对象也很好