我最近不得不在Python2中使用我不喜欢的hack,并且一直在想-原因是什么-为什么不是每个对象都可以被猴子修补,如下面的例子(粗糙,不检查错误,但这只是为了演示):
import requests
def get_page():
req = requests.get("https://stackoverflow.com")
if req.status_code == 200:
yield req
def prepare_some_content_in_file(file_):
with open(file_, 'w') as _file:
_file.write("a texty text")
def patch_file_type():
""" WILL FAIL ! """
file_ = "/tmp/some_so_random_name"
prepare_some_content_in_file(file_)
with open(file_, 'r') as _file:
setattr(_file, "text", _file.read())
yield _file
def patch_func_type():
""" GO AHEAD """
file_ = "/tmp/some_so_random_name"
prepare_some_content_in_file(file_)
pseudo_file = lambda: None
with open(file_, 'r') as _file:
setattr(pseudo_file, "text", _file.read())
yield pseudo_file
print(get_page())
try:
for i in patch_file_type():
print(type(i), i, i.text)
except AttributeError as error:
print(error)
try:
for i in patch_func_type():
print(type(i), i, i.text)
except AttributeError as error:
print(error)
这只与Python2有关,在Python3中它起作用:
Py2输出:
<generator object get_page at 0x7f8afa7143c0>
'file' object has no attribute 'text'
(<type 'function'>, <function <lambda> at 0x7f8afa456668>, u'a texty text')
Py3输出:
<generator object get_page at 0x7f5c37842570>
<class '_io.TextIOWrapper'> <_io.TextIOWrapper name='/tmp/some_so_random_name' mode='r' encoding='UTF-8'> a texty text
<class 'function'> <function patch_func_type.<locals>.<lambda> at 0x7f5c35a02048> a texty text
这个存在的原因很明显是为了有备用的缓存文件,我可以用和请求对象相同的方式对其进行操作,比如调用文本属性,等等
编辑:回应评论:
dir(_file)
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']
dir(pseudo_file) # lambda acutally
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
它们都没有属性__slots__
,这在示例中针对class
进行了讨论。我看看那里有没有什么可以用类似的方法处理的。你知道吗
目前没有回答
相关问题 更多 >
编程相关推荐