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

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

  •  3
  • corvus  · 技术社区  · 6 年前

    是否可以定义一个具有属性的类方法 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 回复  |  直到 6 年前
        1
  •  4
  •   abarnert    6 年前

    每当需要一个不容易静态指定的默认值时,习惯用法是使用一个sentinel值。

    如果 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)
    

    或者,即使是 可能是一种价值,你需要创造一个无人能通过的私人哨兵:

    _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

        2
  •  2
  •   thefourtheye    6 年前

    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)