【问题标题】:How to avoid parameter type in function's name?如何避免函数名称中的参数类型?
【发布时间】:2018-05-11 08:17:34
【问题描述】:

我有一个函数foo,它接受一个参数stuff 东西可以是数据库中的东西,我想创建一个函数,它接受stuff_id,从数据库中获取stuff,执行foo

这是我解决它的尝试: 1/ 创建第二个后缀为from_stuff_id的函数

def foo(stuff):
    do something

def foo_from_stuff_id(stuff_id):
    stuff = get_stuff(stuff_id)
    foo(stuff)

2/修改第一个函数

def foo(stuff=None, stuff_id=None):
    if stuff_id:
        stuff = get_stuff(stuff_id)
    do something

我不喜欢这两种方式。 最pythonic的方法是什么?

【问题讨论】:

  • 您能否提供更多有关您正在尝试做的事情以及您看到的问题的背景信息?
  • 我有一个包含许多路由的 Flask API。每个路由总是相同的,它从路由中使用的参数中获取一个 stuff_id,然后执行一个带有参数 stuff_id 的函数。当我想测试我的函数时,问题是它使用 id 而不是 stuff 对象,所以我想将获取 stuff 对象的逻辑与在 stuff 上执行函数的逻辑分开。

标签: python python-3.x function design-patterns


【解决方案1】:

假设foo 是您的应用程序的主要组件,这是您的第一种方式。每个功能都应该有不同的用途。当您将多种用途组合到一个函数中时,您很容易迷失在长长的代码流中。

但是,如果其他一些功能也可以提供东西,那么就使用第二个。

我要添加的唯一内容是确保向每个函数添加文档字符串 (PEP-257) 以用文字解释函数的作用。如有必要,您还可以将 cmets 添加到您的代码中。

【讨论】:

    【解决方案2】:

    我不是 Python 中类型重载的忠实拥护者,但如果确实需要,我可能会采用这种情况:

    def foo(stuff):
        if isinstance(stuff, int):
            stuff = get_stuff(stuff)
        ...
    

    type annotations 看起来像这样:

    def foo(stuff: Union[int, Stuff]):
        if isinstance(stuff, int):
            stuff = get_stuff(stuff)
        ...
    

    【讨论】:

      【解决方案3】:

      这基本上取决于您如何定义所有这些函数。如果您从另一个模块导入get_stuff,则第二种方法更加Pythonic,因为从OOP 的角度来看,您创建的函数是为了完成一个特定目的,在这种情况下,当您已经定义了get_stuff 时,您不需要在另一个函数中调用它。

      如果get_stuff 没有在另一个模块中定义,那么这取决于您是否使用类。如果您正在使用一个类,并且希望将所有这些模块一起使用,您可以使用一种方法来访问或连接到数据库,并在其他方法中使用该方法,例如 foo

      例子:

      from some module import get_stuff
      
      MyClass:
          def __init__(self, *args, **kwargs):
             # ...
             self.stuff_id = kwargs['stuff_id']         
      
          def foo(self):
              stuff = get_stuff(self.stuff_id)
              # do stuff
      

      或者如果foo 的功能取决于stuff 的存在,您可以拥有一个全局stuff 并简单地检查其验证:

      MyClass:
          def __init__(self, *args, **kwargs):
             # ...
             _stuff_id = kwargs['stuff_id']
             self.stuff = get_stuff(_stuff_id)  # can return None          
      
          def foo(self):
              if self.stuff:      
                  # do stuff
              else:
                  # do other stuff
      

      或者针对这种情况的另一种简洁的设计模式可能是使用调度程序函数(或类中的方法),它根据stuff 的状态将执行委托给不同的函数。

      def delegator(stff, stuff_id):
          if stuff:  # or other condition 
              foo(stuff)
          else:
              get_stuff(stuff_id)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-18
        • 1970-01-01
        • 1970-01-01
        • 2017-09-23
        • 1970-01-01
        • 2020-05-28
        相关资源
        最近更新 更多