我有两个方法,除了一个参数外,所有方法都使用相同的参数,并且运行相同的代码,但其中一个方法需要额外一行。我试图确定最好的方法是清理函数,以免重复代码。这是有问题的方法。
我尝试使用try/except
子句,但是我觉得那很笨拙且过大。我正在考虑向函数中添加一个参数,该参数说明了意图是创建还是编辑文件,但感觉过于严格。
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)
def edit_file(self, file_blob, filename, commit_message, committer_info, branch):
file_blob_sha = self._latest_blob_sha_for_file(branch, filename)
content_url = '{}/{}'.format(self._github_content_url, filename)
json_file_data = self._file_data(file_blob, commit_message, committer_info, branch, file_blob_sha)
response = self._request(content_url, method='PUT', data=json_file_data)
self._handle_errors(response)
答案 0 :(得分:1)
可重用性有时需要使用函数,因此您可能想要一个私有函数来处理edit_file
和create_file
的公共部分,
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)
答案 1 :(得分:0)
create_file
和edit_file
之间的唯一区别是您调用以生成file_blob_sha
的值的函数。您可以假装create_file
调用了一个返回None
的函数(或_file_data
的该参数的默认值)。
定义一个通用基本函数,该基本函数将必要的函数用作参数,而不是将其硬编码到create_file
或edit_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._latest_blob_sha_for_file
的硬编码引用。)
每个其他函数然后只需使用适当的函数参数调用_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_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
请注意,_make_method
本身并不是方法。它只是用来定义create_file
和edit_file
的帮助函数,因此我们在构造类之前将其从类命名空间中删除。
答案 2 :(得分:0)
另一个选择是添加一个新参数:
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)