python - 改变签名的装饰器是一个不好的模式吗?

标签 python

我有许多以下形式的函数:

def parse_file_1(file_name)
    # do something generic
    with open(file_name) as f:
        for line in f:
            # do some generic things with line
            # do some things specific to parse_file_1 with line

为了避免重复大量代码,我使用装饰器重写了它:

def parse_file(parse_function):
     def _parse_file(file_name):
         # do something generic
         with open(file_name) as f:
             for line in f:
                 # do some generic things with line
                 parse_function(line)
     return _parse_file

@parse_file
def parse_file_1(line):
    # do some things specific to parse_file_1 with line

这工作得很好 - 这两个版本在功能上是相同的,正如预期的那样,并且很容易编写这种形式的新函数,而无需复制和粘贴通用代码。

但是,装饰器 parse_file 更改了 parse_file_1 的签名,这让 PyC​​harm 感到困惑(它认为 parse_file_1 具有签名 (line) 而不是 (file_name)),并且通常很难确定 parse_file_1 的签名。

这种做法有多糟糕?(如果很糟糕)有什么好的替代方案(理想情况下不需要太多重复的代码)?或者,让 PyC​​harm 知道 parse_file_1 的真实签名的方法将消除我对当前情况的最大问题。

最佳答案

我不会为此使用装饰器。相反,将解析器函数传递给一个高阶生成器怎么样?

def parse_using(file_name, func):
    with open(file_name) as f:
        for line in f:
            yield func(line)

def parse_foo_line(line):
    return 'This line is very foo-ey: ' + line

parsed_foo = parse_using('foo.txt', parse_foo_line)
parsed_bar = parse_using('bar.txt', parse_bar_line)  # etc...

请注意,这些函数是生成器,因此在迭代之前它们实际上不会解析任何内容(即使如此,它们也只返回一次结果)。如果您想急切地解析事物,请转换为列表。

parsed_foo = list(parse_using('foo.txt', parse_foo_line))

关于python - 改变签名的装饰器是一个不好的模式吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51857799/

相关文章:

python - 如何在Python中为GLFW设置窗口提示

python - A 和 B 的计数差异最大的最短子串

python - 如果自定义 __dir__ 实现,如何获取实际的对象名称列表?

python - 用kivy录制视频

python - 为什么python中子进程的数量会影响子进程的内存消耗?

python - 是否可以删除预训练的 tensorflow 模型中的类别?

python - 人脸识别模型无法正确预测训练图像

python - 在 python setup.py egg_info 上使用 pip 中断安装

python - 将撒克逊与 python 一起使用

python - Pandas:根据数据框中的组合填充缺失值