2014-10-05 30 views
0

我在看别人的代码,试图向他们学习,我对他们所做的一些事情有疑问。或分配

这是从链路

self.sentence = sentence or "" 

是什么或赋值操作符做行16?

我试着自己运行这个,如果句子被定义,那么它被分配给self.sentence,否则如果它没有被分配,我会得到一个NameError异常。

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

+0

如果'sentence'评估为'false',它会将'''''赋值给'self.sentence'。否则(如果'句子'是推定的有效句子),那么它将'self.sentence'赋予'句子'。 – 2014-10-05 04:47:20

+0

@ಠ_ಠ:这似乎更像是一个答案,而不是评论。 – DSM 2014-10-05 04:49:05

+0

https://docs.python.org/2/library/stdtypes.html的5.2节解释了“a或b”的含义。 – 2014-10-05 04:50:46

回答

3

or是懒操作者,并返回第一个值,这是 'trueish'(bool(value) is True)。这个习语被用来分配一个值,或者如果它是空的,则是别的。

在这种情况下,它可能会防止分配None,其值为False,但作者想确定,总是会分配一个string - 在这种情况下为空字符串。

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() 

输出:

[email protected]:~/src/sandbox$ ./def.py 
A real sentence 
<empty> 
[email protected]:~/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() 

输出:

[email protected]:~/src/sandbox$ ./def2.py 
Weird output: 
[1, 2] 
[1, 2] 
Normal output: 
[1, 2] 
[] 
[email protected]:~/src/sandbox$ 

在第一种情况下,你可能期望每个对象以获得自己的空单,但你可以看到,当您添加的东西a ,他们也被追加到b,因为ab共享相同的列表。这不会发生在第二种情况下,因为我们将默认值指定为None而不是[],然后在您的问题中使用该习语。当the_listNone时,the_list or []将评估为[]。如果不是,它只会评估为the_list。它相当于:

if sentence: 
    self.sentence = sentence 
else: 
    self.sentence = ""