Python 有时传递参数而不是参数对象的复杂DICT是否更好?

Python 有时传递参数而不是参数对象的复杂DICT是否更好?,python,parameters,arguments,Python,Parameters,Arguments,我从Java背景开始编写Python已经一年了,我注意到,至少在我的组织中,将复杂参数传递给函数的方式是使用dict或tuple,而不是专门参数类的实例。例如,我们有一个方法,它接受三个dict,每个dict以特定的方式构造,每个dict本身都被格式化为元组。对我来说,构建参数和阅读代码是很复杂的。下面是传递参数的示例: {'[A].X': ((DiscreteMarginalDistribution, ('red', 'blue')), ()), '[A].Y': ((DiscreteCon

我从Java背景开始编写Python已经一年了,我注意到,至少在我的组织中,将复杂参数传递给函数的方式是使用dict或tuple,而不是专门参数类的实例。例如,我们有一个方法,它接受三个dict,每个dict以特定的方式构造,每个dict本身都被格式化为元组。对我来说,构建参数和阅读代码是很复杂的。下面是传递参数的示例:

{'[A].X': ((DiscreteMarginalDistribution, ('red', 'blue')), ()),
 '[A].Y': ((DiscreteConditionalDistribution, ('yellow', 'green'), ('red', 'blue')),
           (IdentityAggregator('[A].X'), ))
我的问题是:

  • 像这样传递dicts/元组是一种常见的Python习惯用法吗
  • 如果有的话,您什么时候编写Python代码来使用后者(参数实例)?例如,当嵌套结构超过某个复杂性阈值时
  • 提前谢谢

    • 是的,为了减少参数的数量,通常会向Python函数传递字典。具有正确键命名的字典样式配置比仅使用元组更具可读性

    • > P>我认为动态构造自定义配置类的专用实例是非常罕见的。我会坚持用字典。如果您的config dict和它的使用者不同步,您会得到
      KeyError
      s,这非常适合调试

    一些建议和理由:

    如果应用程序的某些部分需要非常复杂的配置,我认为配置一个适当地表示当前配置的配置对象是个好主意。然而,在我的项目中,我从来没有将这些对象作为函数参数传递。这有味道。在一些应用程序中,我有一个恒定的全局配置对象,在引导过程中设置。这样的对象是全局可用的,并被视为“不可变的”

    单个函数不应该太复杂,以至于需要检索极其复杂的配置。这表明您应该将代码分成几个组件,每个子单元都有一个相当简单的参数化

    如果函数的运行时配置比普通(关键字)参数容易处理的复杂度稍高,那么传递字典是绝对常见的,也就是说作为“leightweight”配置对象。通过选择关键名称进行深思熟虑,使这种方法具有很好的可读性。当然,如果一个级别不足以满足您的用例,您也可以建立层次结构

    最重要的是,请注意,在许多情况下,最好的方法是使用普通参数规范,通过函数签名明确定义函数的参数化:

    def f(a, b, c, d, e):
        ...
    
    在调用代码中,您可以在字典中准备这些参数的值:

    arguments = {
        a = 1,
        b = 2,
        c = 3,
        d = 4,
        e = "x"
    }
    
    然后在函数调用时使用Python的snytic sugar进行关键字扩展:

    f(**arguments)
    

    我已经用Python编程了大约2-3个月了,我也想知道这一点。。。我的意思是,如果你的dict是以某种方式构造的,如果你添加/删除一个字段,那么一切都会中断,那么你最好使用一个类来实现这一点。特别是在dict键显然是字段名的情况下。那么较小的类型的东西呢?就像一个函数在图形上画一个特定的点,并接受一个参数,该参数具有:坐标、颜色、附加文本等。将这样的参数作为对象而不是使用dict难道不是明智的吗?第一个选择总是有一个显式定义的函数调用签名。尤其是在设计公共API的情况下。这可能会变得复杂,但它是明确的,仍然易于阅读。极端情况是,例如,matplotlib API:或pandas API:我同意参数。但是在某些情况下,我觉得dict被错误地使用了,你看,dict是一种映射类型,它将某些值映射到其他值,但它不必是字段名,就像它经常被滥用一样。我的意思是对象是将字段名映射到值的dict,为什么不在将字符串(字段名)映射到值的情况下使用对象呢?(从我肤浅的经验来看,我发现使用dict来实现这一点是很常见的),因为Python对象比简单的字典引入了更多的复杂性。如果您不需要这种复杂性,那么为什么要使用它呢?比要求更复杂是一个糟糕的设计选择。请不要使用对象,因为
    obj.attr
    d[“attr”]
    好看。非常感谢您的回答和评论!