或者在任务中

时间:2014-10-05 04:44:58

标签: python

我正在寻找别人的代码,试图向他们学习,我对他们已经完成的事情有疑问。

这是链接

的第16行
self.sentence = sentence or ""

分配操作员做什么或做什么?

我自己尝试过运行此功能,如果定义了句子,则将其分配给self.sentence,否则如果未分配,则会收到NameError异常。

https://github.com/xavier/exercism-assignments/blob/master/python/bob/bob.py

2 个答案:

答案 0 :(得分:3)

or是一个惰性运算符,并返回第一个值,即'trueish'(bool(value) is True)。这个成语用于分配值,或者如果它是空的,则使用其他内容。

在这种情况下,它可能会防止分配None,其评估为False,但作者希望确定,将始终为string分配 - 并且为空字符串在这种情况下。

答案 1 :(得分:2)

在示例代码中,如果__init__()具有默认参数,则更有意义:

class Fake:
    def __init__(self, sentence=None):
        self.sentence = sentence or '<empty>'

    def print_me(self):
        print(self.sentence)

a = Fake('A real sentence')
b = Fake()

a.print_me()
b.print_me()

输出:

paul@local:~/src/sandbox$ ./def.py
A real sentence
<empty>
paul@local:~/src/sandbox$ 

在这种特殊情况下,def __init__(self, sentence='<empty>'):后跟self.sentence = sentence同样可以做得很好,但在处理列表等可变对象时这可能更有用,因为def __init__(self, sentence=[]):只会评估一次,所有类都将引用相同的默认列表。改为将None指定为默认值,并在__init__()中创建单独的空列表可以避免此行为。

例如:

#!/usr/bin/env python

class Weird:
    def __init__(self, the_list=[]):    # <--- Don't do this
        self.the_list = the_list

    def append(self, value):
        self.the_list.append(value)

    def print_me(self):
        print(self.the_list)

class Normal:
    def __init__(self, the_list=None):
        self.the_list = the_list or []

    def append(self, value):
        self.the_list.append(value)

    def print_me(self):
        print(self.the_list)

print("Weird output:")
a = Weird()
b = Weird()
a.append(1)
a.append(2)
a.print_me()
b.print_me()

print("Normal output:")
c = Normal()
d = Normal()
c.append(1)
c.append(2)
c.print_me()
d.print_me()

输出:

paul@local:~/src/sandbox$ ./def2.py
Weird output:
[1, 2]
[1, 2]
Normal output:
[1, 2]
[]
paul@local:~/src/sandbox$ 

在第一种情况下,您可能希望每个对象都有自己的空列表,但是您可以看到在向a追加内容时,它们也会附加到b,因为{{1 }和a共享相同的列表。在第二种情况下不会发生这种情况,因为我们将默认值指定为b而不是None,然后在您的问题中使用了惯用法。当[]the_list时,None将评估为the_list or []。如果不是,它只会评估为[]。它相当于:

the_list