【问题标题】:syntax error: non-keyword arg after keyword arg语法错误:关键字 arg 后的非关键字 arg
【发布时间】:2017-06-01 12:54:52
【问题描述】:

我在 spyder 中使用 Python 2.7.13。

def test(a,b,c='c',*args):
    for item in args:
        print item

此函数定义在 Python 2.7 中有效,但一旦我尝试传入 args,它就会在关键字 arg 之后给出 非关键字 arg 错误:

test(1,2,c='c',10,11)

给出这个:

non-keyword arg after keyword arg

但是这个:

test(1,2,3,4,5)

正在工作。

自从将*args 放在c='c' 之前,我不确定这里有什么问题

def test(a,b,*args,c='c'):
    for item in args:
        print item

这给了我函数定义的错误。

以上代码只是一个虚拟示例,原始代码如下所示:

def export_plot_as_mat(fname, undersamp, undersamp_type, n_comp, b_s, n_iter, fit_alg, transf_alg, alpha_train, alpha_test, export_info=False, *args):

    info = ('undersampling=' + str(undersamp) + ' undersampling_type=' +str(undersamp_type) + 
        ' n_comp=' + str(n_comp) + ' batch_size=' + str(b_s) + 
        ' n_iter=' + str(n_iter) + ' fit_alg=' + str(fit_alg) + 
        ' transform_alg=' + str(transf_alg) + ' alpha_train=' + 
        str(alpha_train) + ' alpha_test=' + str(alpha_test))

    d = [(str(args[i]), args[i]) for i in range(len(args))]

    if export_info:
        d.append('info',info)
    sp.io.savemat(fname + '.mat', d)

我希望可以选择导出用于构建我要导出的数据的参数。

【问题讨论】:

  • 更改顺序:test(1,2,10,11,c='c')。 Python 会做正确的事并收集*args 中的所有非关键字参数。
  • @Boldewyn 这可能在 python 3.x 中有效,但在 python 2.7 中这给了我错误test() got multiple values for keyword argument 'c'
  • @PedrovonHertwig 我希望 args 具有不同的大小,这就是为什么我不传递常规参数
  • 副本更倾向于 Python 3 解决方案,而 OP 使用的是 Python 2.7。
  • @AryaMcCarthy 因为在这种情况下定义的顺序是正确的,所以这不是同一个问题

标签: python python-2.7 function


【解决方案1】:

定义很好,因为c 可以在位置上指定。 调用是问题所在;您在另一个位置参数之前指定了一个关键字参数。

Python 2.x 无法定义仅关键字参数。

【讨论】:

  • 如上所述,将 *args 放在关键字之前会在函数定义中引发错误
  • 是的,这是第二个错误。它不会改变第一个定义很好的事实。
  • 无论你在 Python 2.x 中如何定义test,像test(1,2,c=3,4,5) 这样的调用都是非法的;您不能在关键字参数之后指定位置参数。
  • 所以解决这个问题的一种方法是在**kwargs 参数中定义c 并用kwargs[0] 调用它,不知何故我认为它可能会在定义后以问题的方式工作没问题。
  • 这个定义没问题,因为 Python 2 没有明确区分“可选位置参数”和“关键字参数”。如果您定义def test(a, b, *args, **kwargs),则c 只能 指定为关键字参数。 (这与我之前声称的 Python 2 没有仅关键字参数略有不同,因为在这种情况下您没有显式声明 c;您只是声称 test 可以采用任意关键字参数,但是你不保证他们都会被承认。)
【解决方案2】:

这是 Python 2.x 如何进行参数解析的一个有趣的侧面案例。粗略地说,Python 有一些关于如何将传递给函数的参数与它所期望的参数“匹配”的逻辑,并且这种逻辑在 Python 3 中发生了变化。

获得所需内容的最简单方法是接受**kwargs 而不是指定c=0,并手动执行默认参数。

【讨论】:

  • 我认为这是一种解决方案,但最终它有点难看。该定义在某种程度上与函数调用本身相矛盾
【解决方案3】:

这里有几件事。

将 test() 中的 c = 'c' 更改为 'c'

你也可以把你的最后一个参数放在一个列表中,以便在同一行打印它们。或保持原样以将它们打印在单独的行中。

def test(a,b,c='c',*args):
    for item in args:
        print item

test(1,2,'c',[10,11])

结果:

[10, 11]

对于参数c = 'c',您可以在那里传递您想要的任何内容并与c进行交互:

举个例子:

def test(a,b,c='c',*args):
    print c
    for item in args:
        print item


test(1,2,'g',10,11)

结果:

g
10
11

【讨论】:

  • 我想将 'c' 指定为 c='c' 以查看分配给该 'c' 的内容
  • 你能说清楚一点吗?你是什​​么意思看看'c'被分配了什么。也许在= 的两侧使用不是c 的示例,这样我就可以理解您的需要。
  • 在更新的问题中,参数是export_info=False,因此在函数调用中,无论是应该导出信息还是只导出参数,都是可见的。只是通过 TrueFalse 在 imo 中是不可读的
  • 根据这个Link我认为这在python 2.7中是不可能的。我不确定 2.7 是否有解决方法,但在 python 3 中可能可行。
猜你喜欢
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多