我有多种形式的函数:
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
的签名,这混淆了PyCharm(它认为parse_file_1
具有签名(line)
而不是(file_name)
),并且通常,很难确定parse_file_1
的签名。
这是多么糟糕的做法,以及(如果不好的话)有什么好的选择(理想情况下不需要太多重复的代码)?另外,让PyCharm知道parse_file_1
的真实签名的方法可以消除我目前遇到的最大问题。
答案 0 :(得分:3)
我不会为此使用装饰器。相反,将解析器函数传递给的高阶生成器怎么样?
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))