在python中,什么时候可以省略?

时间:2016-06-22 08:50:51

标签: python class

下面的代码将 Duck 类定义为从 Bill 类和 Tail 类合成。我的问题是,对于 Duck 类定义中的 about()方法,为什么可以编写bill.descriptiontail.length?这里省略了self吗?如果是,我什么时候可以省略self?我可以在__init__方法中省略它们吗?

class Bill(): 
    def __init__(self, description):
        self.description = description 
class Tail(): 
    def __init__(self, length): 
        self.length = length 
class Duck(): 
    def __init__(self, bill, tail): 
        self.bill = bill
        self.tail = tail 
    def about(self): 
        print('This duck has a', bill.description, 'bill and a', tail.length, 'tail')
tail = Tail('long')
bill = Bill('wide orange') 
duck = Duck(bill, tail)
duck.about()

输出如下, enter image description here

4 个答案:

答案 0 :(得分:4)

在Python中,显式优于隐式,并且在访问成员变量时不能省略<link rel="stylesheet" type="text/css" href="https://bootswatch.com/bower_components/bootstrap/dist/css/bootstrap.min.css" /> <div class=col-sm-6> <form> <label class="control-label" for="code">Code</label> <div class="controls"> <input type="password" name="code" id="code" class="form-control" placeholder="code" /> </div> </form> </div> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script> <script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>

在您的情况下,您实际使用全局范围内的名称。要触发错误,只需将创建的对象分配给其他名称:

self

答案 1 :(得分:4)

简而言之:只要您想访问当前实例的属性(数据属性,属性或方法),就必须 使用self.

有一个更详细的答案:在def语句中使用class时,您创建的不是&#34;方法&#34;但是一个简单的功能。当查找一个类或实例属性(Duck.aboutduck.about)时,这个函数将被包装(与它所查找的类和实例一起)在一个可调用的{{1}中将自动注入实例(或类)对象作为函数调用的第一个参数的对象。您可以在此处阅读全部详细信息:https://wiki.python.org/moin/FromFunctionToMethod

正如其他已经提到的那样,您的代码段只是意外地“#34;工作&#34;因为它最终会查找恰好定义的全局名称,并且一旦未定义这些名称就会中断:

method

=&GT;崩溃时遇到# tail = Tail('long') # bill = Bill('wide orange') duck = Duck(Bill('wide orange'), Tail('long')) duck.about()

如果重新绑定这些全局名称,您也会得到意想不到的结果,即:

NameError

=&GT; Duh,为什么它打印&#34;短的norvegian蓝&#34; ???

答案 2 :(得分:2)

你可以这样写,因为你已经定义了一个全局变量billtail,这里引用了它。

...
    def about(self): 
        print('This duck has a', bill.description, 'bill and a', tail.length, 'tail')
                         # these ^^^^                            ^^^^

# refer to these vvvv
tail = Tail('long')
bill = Bill('wide orange') 

所以这不符合你的想法。如果您想引用当前对象的billtail属性, 不能忽略self,则必须为self.bill并且self.tail。如果重命名或删除这些全局变量,您的代码将会中断。

答案 3 :(得分:1)

你应该避免这样做。 bill中的about()将引用外部范围中的bill,在本例中为全局范围。因此,当您更改该全局变量的值时,about()的输出也会受到影响:

>>> tail = Tail('long')
>>> bill = Bill('wide orange')
>>> duck = Duck(bill, tail)
>>> duck.about()
This duck has a wide orange bill and a long tail
>>> bill = Bill('DIFFERENT')
>>> duck.about()
This duck has a DIFFERENT bill and a long tail

为了引用传递给bill并存储在实例中的tailDuck()个对象,您始终需要使用self.bill和{{1 }}