【问题标题】:Non-Default parameter follows default parameters非默认参数遵循默认参数
【发布时间】:2019-12-14 12:07:21
【问题描述】:

我不断收到关于我的函数参数的错误消息。

我见过一些其他类似的问题,但我很难理解答案,而且这些人也有不同的情况,更复杂。

def check(user_answer='', list_of_blanks, letters):
    x = 0
    for letter in letters:
        if letter == user_answer:
            list_of_blanks[letters.index(user_answer)] = user_answer
            x += 1
    if x == 0:
        return False
    else:
        str(list_of_blanks)
    list_of_blanks = ''.join(list_of_blanks)
    return list_of_blanks

pycharm 突出显示“list_of_blanks, letters”(函数参数)并给我错误提示:

Non-Default parameter follows default parameter.

如果我尝试将参数默认为一个空列表,如下所示:

list_of_blanks=[], letters=[]

然后我得到这个错误:

Default argument value is mutable.

【问题讨论】:

  • 可变的东西是一个警告
  • 阅读here 了解定义函数参数的不同方式

标签: python python-3.x arguments parameter-passing


【解决方案1】:

是否可以切换参数的位置?然后你可以写:

def check(list_of_blanks, letters, user_answer=''):

【讨论】:

    【解决方案2】:

    在位置参数之前不能有非位置参数 (param=value)。

    def func(positional1, positional2, nonpositional=10)
    

    这主要是因为您不需要指定非位置参数的名称。

    func(10, 50, nonpositional=60) == func(10, 50, 60)

    【讨论】:

    • 您不需要指定任何参数的名称。准确的说法是,您不需要传递非位置参数根本,那会弄得一团糟......
    • 它们具有默认参数这一事实暗示了这一点。
    • 好的,我只是说您声称的主要原因并不是真正的问题。因为如果指定名称是问题,那么即使 OP 中的定义错误,我们也可以调用check('answer', [1, 2], "abc")。我的观点是,真正的问题是它可以被省略,然后你的位置就会改变
    【解决方案3】:

    给参数一个默认值使其成为可选的。您不能在非可选参数之前有可选参数,因为这样就不清楚您要分配哪些插槽以及不分配哪些插槽。您也许可以提出一组复杂的规则来确定如何解释参数,但 Python 会尝试避免不必要的复杂性、歧义和违反直觉的行为。

    您可以通过多种方式解决此问题:

    1. 将默认参数移到列表末尾:

       def check(list_of_blanks, letters, user_answer=''):
      
    2. 将所有其他参数也设为可选:

       def check(user_answer='', list_of_blanks=(), letters=()):
      

      使用不可变的元组可以避免对默认列表的意外(和永久性)修改。

    3. 完全删除默认参数:

      def check(user_answer, list_of_blanks, letters):
      

      坦率地说,这似乎是您的最佳选择。从概念上讲,函数最重要的参数是第一位的。除非您的函数有副作用,否则将这些参数设为可选似乎有些不足。

    4. 将其他参数设为必需,但仅限关键字:

      def check(user_answer='', *, list_of_blanks, letters):
      

      您将无法再以 check('abc', ['b', 'c'], ['a']) 的身份调用该函数,因为无法再将 list_of_blanks 和 letters 指定为位置参数。您现在必须使用关键字check('abc', list_of_blanks=['b', 'c'], letters=['a']) 调用。但现在第一个参数无疑是可选的,因此您可以执行 check(letters=['a'], list_of_blanks=['b', 'c']) 之类的操作。

    我个人的偏好,按降序排列是 3、4、1、2。我认为你最好的选择是没有可选参数,但我可以想象你正处于一个想要使用关键字的阶段 -无论设计含义如何,都只是参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-04
      • 2018-06-30
      • 2021-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多