这是什么" __ init __"在这段代码中做什么?

时间:2016-03-03 01:37:59

标签: python lambda

我不理解以下代码:

Resource is already using the URI

我知道self._create_context是一个生成器,但执行 init 后self._create_context会保留什么?生成器表达式中的lambda是做什么的?

3 个答案:

答案 0 :(得分:1)

该代码令人困惑地简洁。我已经使用了更明确的东西。

def __init__(self, create_context=None):
    if create_context:
        self._create_context = create_context
    else:
        self._create_context = lambda *_: nop_context

可以说我应该尊重相同的if create_context is not None:,取决于create_context通常是什么(我假设它是一些可调用的,以后可以调用懒惰地创建上下文)。

答案 1 :(得分:1)

self._create_context不是生成器,除非create_context参数中传递的值恰好是生成器。否则,括号只是包装表达式,以便它可以跨越多行,可能是为了提高可读性。

然而,所有这个功能都是将默认值应用于self._create_context。它与此基本相同:

class nop_context(object):
    def __enter__(self):
        pass
    def __exit__(self, *excinfo):
        pass

def __init__(self, create_context=lambda *_: nop_context):
    self._events = []
    self._create_context = create_context

*_只是一种允许函数接受任意数量参数的方法。我更愿意看*args代替*_,因为它是一个更易识别的Python习语。

注意:在定义__init__方法时,我上面显示的方式为类创建了一个lambda函数。严格来说,功能是可变的。这意味着对函数对象的任何更改都将影响相应类的所有实例。它类似于使用可变默认值(例如列表)的时间。虽然在列表的情况下它可能是一个问题,但修改一个函数并不常见,所以它不应该是一个问题。

答案 2 :(得分:0)

如果你把它分成两行,这更容易分辨:

create_context if create_context is not None
else lambda *_: nop_context

(注意:这不是像我刚才那样的有效语法)

如果self._create_context不是create_context,那么

create_context将是None,但如果是None,那么我们需要使用默认值。在这种情况下,默认值是lambda函数,它将*_作为参数,并返回nop_context*_一开始可能有点混乱,但它与*args相同:这意味着我们可以采用任意数量的参数。我们将这些参数存储在名为_的元组中。使用_是因为我们不会使用这些参数。无论它们是什么,我们将始终返回nop_context