python中的类方法:来自self属性的默认kwargs

时间:2018-06-18 05:04:19

标签: python kwargs

是否可以定义一个以self属性作为默认关键字参数的类方法?即我想做一些与以下相同的事情:

class Foo:
    def __init__(self, bar):
        self.bar = bar

    def do_a_thing(self, my_arg=self.bar):
        do_something_else(my_arg)

当然这会引发错误:

x = Foo(y)
x.do_a_thing()

NameError: name 'self' is not defined

希望很清楚我希望得到什么样的行为。致电x.do_a_thing()应该等同于x.do_a_thing(my_arg=x.bar)

有办法做到这一点吗?

2 个答案:

答案 0 :(得分:4)

每当你想要一个不能静态指定的默认值时,这个习惯用法就是使用一个标记值。

如果None不是任何人可能传递的有效值,请使用:

def do_a_thing(self, my_arg=None):
    if my_arg is None:
        my_arg = self.bar
    do_something_else(my_arg)

或者,如果没有任何有效的假值:

def do_a_thing(self, my_arg=None):
    if not my_arg:
        my_arg = self.bar
    do_something_else(my_arg)

或者,如果偶数None可能是一个值,您需要创建一个没人会传递的私人哨兵:

_sentinel = object()
def do_a_thing(self, my_arg=_sentinel):
    if my_arg is _sentinel:
        my_arg = self.bar
    do_something_else(my_arg)

顺便说一下,将其称为“默认关键字参数”意味着严重的误解。函数定义中的默认值的语法看起来类似于函数调用中关键字参数的语法这一事实是巧合。特别是,这不是关键字参数,可以在不使用关键字参数的情况下调用它。例如:

my_thing.do_a_thing(20)

如果您确实想要一个仅限关键字的参数,则必须在*之后(或*args之后,如果您有其中一个参数)。并且,因为这些是完全不相关的功能,所以您可以使用没有默认值的仅关键字参数:

def do_a_thing(self, *, my_arg):
    do_something_else(my_arg)

“kwargs”通常不用作“关键字参数”或“关键字参数”的简写,而是用于收集所有未知关键字参数的**kwargs参数。

答案 1 :(得分:2)

评估do_a_thing的参数时,不会引用self。这就是为什么它不起作用。

您需要使用常见的默认参数模式,例如

class Foo:
    def __init__(self, bar):
        self.bar = bar

    def do_a_thing(self, my_arg=None):
        if my_arg is None:
            my_arg = self.bar
        do_something_else(my_arg)