代码之家  ›  专栏  ›  技术社区  ›  SapphireSun

两个关键字参数位置的交换引发错误

  •  0
  • SapphireSun  · 技术社区  · 14 年前

    我有个奇怪的问题。我知道在python中,Kwargs遵循args,所以我检查了一下,这不是问题所在。问题是:

    好的:

    def __init__(self, sample_rate, label=u"", data=[] ):

    TypeError: __init__() 获取关键字参数“data”的多个值:

    def __init__(self, sample_rate, data=[], label=u""):

    引发错误的调用行如下所示:

    def __getslice__(self, start, stop):
        return Channel(self.sample_rate, self.label, data=list.__getslice__(self,start,stop))
    

    完整代码:

    class Channel(list):
      sample_rate = 0
    
      def __init__(self, sample_rate, data=[], label=u"" ):
         list.__init__(self,data)
         self.sample_rate = sample_rate
         self.label = label
    
      @property
      def nyquist_rate(self):
          return float(self.sample_rate) / 2.0
    
      def __getslice__(self, start, stop):
          return Channel(self.sample_rate, self.label, data=list.__getslice__(self,start,stop))
    

    谢谢您!

    3 回复  |  直到 14 年前
        1
  •  4
  •   sttwister    14 年前

    在第二个版本中( def __init__(self, sample_rate, data=[], label=u""): ,第二个位置参数(调用时,这意味着不计算 self )是 data 但在 __getslice__ ,您传递的第二个参数是 label . 因此,您应该将label作为第二个参数,或者将函数调用更改为:

    return Channel(self.sample_rate, label=self.label, data=list.__getslice__(self,start,stop))
    
        2
  •  4
  •   Ofri Raviv    14 年前

    你用的是

    Channel(self.sample_rate, self.label, data=list.__getslice__(self,start,stop))
    

    注意,第二个参数没有关键字,所以解释器假定这是 data 参数(因为这是它们在函数中定义的顺序)。如果你加上 label= 它应该解决它。

    但是,您的代码中有一个更重要的错误: 切勿将[]用作默认值。原因是此代码在函数定义时被评估。每次调用此代码时, 数据 参数, 您将得到与默认值相同的列表 . 第一次之后它可能不会是空的!对于所有可变数据类型都是这样。正确的方法是 None 作为默认值,如果参数值为“无”,则在函数(每次运行的代码)内部初始化一个新的[]。 (大卫·古德格在 Default Parameter Values )

        3
  •  2
  •   Torsten Marek    14 年前

    问题是,在调用代码中,有两个位置参数:

    return Channel(self.sample_rate, self.label, data=list.__getslice__(self,start,stop))
    #              sample_rate (pos) data (pos)  data (kw)
    

    在python 2.x中,位置参数和关键字参数之间没有区别 在函数定义中 . 调用函数时,使用函数调用中的位置参数从左到右填充参数,然后绑定所有关键字参数。在你的情况下, data 由位置参数和关键字参数绑定。它在另一种情况下工作,因为第二个位置参数用于 label 数据 只获取关键字参数。

    推荐文章