Python 如何重构两个只需要一个参数的函数?
我有两个方法,除了其中一个方法的一行代码外,它们都使用相同的参数并运行相同的代码。我正试图决定最好的方法是清理函数,这样我就不会重复代码。以下是正在讨论的方法 我试过使用Python 如何重构两个只需要一个参数的函数?,python,design-patterns,Python,Design Patterns,我有两个方法,除了其中一个方法的一行代码外,它们都使用相同的参数并运行相同的代码。我正试图决定最好的方法是清理函数,这样我就不会重复代码。以下是正在讨论的方法 我试过使用try/except子句,但我觉得这太笨拙了。我正在考虑向一个函数添加一个param,该函数会记录是否要创建或编辑一个文件,但这感觉太严格了 def create_file(self, file_blob, filename, commit_message, committer_info, branch): json_f
try/except
子句,但我觉得这太笨拙了。我正在考虑向一个函数添加一个param,该函数会记录是否要创建或编辑一个文件,但这感觉太严格了
def create_file(self, file_blob, filename, commit_message, committer_info, branch):
json_file_data = self._file_data(file_blob, commit_message, committer_info, branch)
content_url = '{}/{}'.format(self._github_content_url, filename)
response = self._request(content_url, method='PUT', data=json_file_data)
self._handle_errors(response)
可重用性有时需要使用函数,因此您可以使用类似私有函数的函数来处理
edit\u文件
和create\u文件
的公共部分:
def _process_file(json_file_data, filename):
content_url = '{}/{}'.format(self._github_content_url, filename)
response = self._request(content_url, method='PUT', data=json_file_data)
self._handle_errors(response)
def create_file(self, file_blob, filename, commit_message, committer_info, branch):
json_file_data = self._file_data(file_blob, commit_message, committer_info, branch)
_process_file(json_file_data, filename)
def edit_file(self, file_blob, filename, commit_message, committer_info, branch):
file_blob_sha = self._latest_blob_sha_for_file(branch, filename)
json_file_data = self._file_data(file_blob, commit_message, committer_info, branch, file_blob_sha)
_process_file(json_file_data, filename)
create_file
和edit_file
之间唯一的区别是调用函数为file_blob_sha
生成值。您可以假装create\u file
调用了一个返回None
的函数(或者该参数的默认值为\u file\u data
)
定义一个公共基函数,将必要的函数作为参数,而不是将其硬编码到create\u file
或edit\u file
的主体中
def _base(self,
file_blob,
filename,
commit_message,
committer_info,
branch,
fn):
file_blob_sha = fn(branch, filename)
json_file_data = self._file_data(file_blob, commit_message, committer_info, branch, file_blob_sha)
content_url = '{}/{}'.format(self._github_content_url, filename)
response = self._request(content_url, method='PUT', data=json_file_data)
self._handle_errors(response)
(注意,正文看起来与edit_file
一模一样;您刚刚用一个函数参数替换了对self的硬编码引用
然后,您的其他每个函数只需使用适当的函数参数调用\u base
。对于create_file
,这是一个显式函数,它忽略其参数并返回None
def create_file(self, file_blob, filename, commit_message, committer_info, branch):
return self._base(
file_blob,
filename,
commit_message,
committer_info,
branch,
lambda *args: None)
def edit_file(self, file_blob, filename, commit_message, committer_info, branch):
return self._base(
file_blob,
filename,
commit_message,
committer_info,
branch,
self._latest_blob_sha_for_file)
您可以通过定义一个函数来进一步简化样板文件,该函数通过关闭函数参数返回适当的方法。在这种方法中,您还没有访问self
的权限来创建要在edit\u file
中使用的绑定方法,因此您必须显式地将self
传递给回调函数
class SomeClass:
def _make_method(fn):
def _base(self, file_blob, filename, commit_message, committer_info, branch):
file_blob_sha = fn(self, branch, filename)
json_file_data = self._file_data(file_blob, commit_message, committer_info, branch, file_blob_sha)
content_url = '{}/{}'.format(self._github_content_url, filename)
response = self._request(content_url, method='PUT', data=json_file_data)
self._handle_errors(response)
return _base
def _latest_blob_sha_for_file(self, branch, filename):
...
create_file = _make_method(lambda *args: None)
edit_file = _make_method(_latest_blob_sha_for_file)
del _make_method
请注意,\u make\u方法
本身并不是一种方法;它只是一个用于定义create_file
和edit_file
的帮助函数,因此我们在构建类之前将其从类名称空间中删除。另一个选项是添加一个新参数:
def manipulate_file(self, file_blob, filename, commit_message, committer_info, branch, edit = False):
args = [file_blob, filename, commit_message, committer_info, branch]
if edit:
file_blob_sha = self._latest_blob_sha_for_file(branch, filename)
args += [file_blob_sha]
content_url = '{}/{}'.format(self._github_content_url, filename)
json_file_data = self._file_data(*args)
response = self._request(content_url, method='PUT', data=json_file_data)
self._handle_errors(response)
将公共代码放在一个单独的函数中,并从问题中显示的两个函数中分别调用它。
def manipulate_file(self, file_blob, filename, commit_message, committer_info, branch, edit = False):
args = [file_blob, filename, commit_message, committer_info, branch]
if edit:
file_blob_sha = self._latest_blob_sha_for_file(branch, filename)
args += [file_blob_sha]
content_url = '{}/{}'.format(self._github_content_url, filename)
json_file_data = self._file_data(*args)
response = self._request(content_url, method='PUT', data=json_file_data)
self._handle_errors(response)