gpt4 book ai didi

python - 如果装饰器更改了 API,我应该如何处理装饰函数的文档字符串?

转载 作者:太空宇宙 更新时间:2023-11-04 01:31:01 25 4
gpt4 key购买 nike

背景

我有一个库,其中包含多个读取或写入文件的函数。每个函数都接受文件作为第一个参数,可以是文件对象或文件名。因此,所有函数的开头都是相同的一段代码,类似如下:

if isinstance(f, str):
file_obj = open(f, 'w')
else:
file_obj = f

现在我想我可以在装饰器中写一次并将所有函数包装在其中,而不是重复自己。 (我也在考虑在同一个装饰器中实现上下文管理器接口(interface)。)

所以如果我这样做,函数将如下所示:

@file_aware('w')
def function(f, *args, **kwargs):
"""Do stuff. `f` can be file object or file name"""
for line in f:
....

问题

我担心的是现在函数的文档字符串与其下面的代码不对应。(我打算用 functools.wraps 保留修饰函数的文档字符串。)会不会降低代码的可读性/可维护性/透明性?据我了解,装饰器可以很容易地来来去去,但与此同时,这有点改变了 API(我不打算删除该功能)。这种情况下的“最佳实践”方式是什么?

我可以考虑在装饰器中自动处理文档字符串,但是:

  • 这不是最自然的事情;
  • 这只对在线文档有意义,对阅读源代码的人没有帮助(相反,相反)。

最佳答案

一种选择是将文档字符串传递给装饰器。这样你仍然可以通过函数定义获得一个文档字符串来阅读源代码,但是如果你要更改或删除装饰器,你最终不会得到一个不正确的文档字符串。

例如:

@file_aware(docstring="Do stuff. `f` can be file object or file name", mode="r")
def function(f, *args, **kwargs):
for line in f:
....

您的 file_aware 装饰器可能看起来像这样:

def file_aware(docstring, mode):
def deco(func):
@functools.wraps(func)
def wrapped(f, *args, **kwargs):
if isinstance(f, str):
file_obj = open(f, mode)
else:
file_obj = f
return func(file_obj, *args, **kwargs)
wrapped.__doc__ = docstring
return wrapped
return deco

关于python - 如果装饰器更改了 API,我应该如何处理装饰函数的文档字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13938230/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com