Python中的**kwargs和self作为参数

4

我在python方面没有太多经验,但我正在学习**kwargs

读了很多之后,我对**kwargs有了一些了解,但我有一个小问题或者说我可能没有理解某些东西。

那么这个有效

def test_var_kwargs(farg, **kwargs):
    print "formal arg:", farg
    for key in kwargs:
        print "another keyword arg: %s: %s" % (key, kwargs[key])

test_var_kwargs(farg=1, myarg2="two", myarg3=3)

并且打印:

正式参数:1

另一个关键字参数:myarg2:two

另一个关键字参数:myarg3:3

但如果该函数是实例函数,则必须包括self

def test_var_kwargs(self, farg, **kwargs):
        print "formal arg:", farg
        for key in kwargs:
            print "another keyword arg: %s: %s" % (key, kwargs[key])
    
self.test_var_kwargs(farg=1, myarg2="two", myarg3=3)

但这会产生一个错误:
TypeError: test_var_kwargs() takes exactly 2 arguments (1 given)

我理解我需要像这样传递self:

我明白我需要像这样传递self:

self.test_var_kwargs(self, farg=1, myarg2="two", myarg3=3)

为什么我必须在类实例的方法中包含self作为参数?


1
你能否包含“类函数”的完整代码示例?我认为你可能误解了它。 - Wessie
1
只需将 frag=1 转换为 1 - namit
1
因为它只将 farg=1 视为关键字参数。 - Ashwini Chaudhary
@Wessie 不要误解类。那不是重点。 - Jimmy Kane
1个回答

7

在这种情况下,您不能将farg用作关键字参数;它不能被解释为位置参数和关键字参数,Python在此情况下将其解释为关键字参数。

使用

self.test_var_kwargs(self, 1, myarg2="two", myarg3=3)

函数作为描述符;当在实例上查找时,它们会被包装在一个称为方法的新对象中,当调用时,该方法自动将实例作为第一个参数添加到函数中。这个包装器本质上是这样的:

class Method(object):
    def __init__(self, function, instance, cls):
        self.func = function
        self.instance = instance
        self.cls = cls

    def __call__(self, *args, **kw):
        return self.func(self.instance, *args, **kw)

你的farg关键字参数随后被归为**kw并传递给底层函数,而*args则为空。

但是你定义的test_var_kwargs方法有一个位置参数(紧挨着self),因此会引发异常。


但是为什么我必须在参数中包含self呢? - Jimmy Kane
我看不出farg同时被解释为位置参数和关键字参数。使用正确的类/对象语法,我的机器产生了预期结果。 - Kyle Strand
在实例方法的定义中,您只需要包含“self”。当调用方法时,您永远不必包含对self的引用,这是隐式完成的。 - Zoran Pavlovic
@KyleStrand:那是我措辞不当,已经更新并扩展了答案。 - Martijn Pieters
谢谢。终于完成了。也感谢@ZoranPavlovic。 - Jimmy Kane

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接