Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何重构两个只需要一个参数的函数?_Python_Design Patterns - Fatal编程技术网

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)