下面的代码将 Duck 类定义为从 Bill 类和 Tail 类合成。我的问题是,对于 Duck 类定义中的 about()方法,为什么可以编写bill.description
和tail.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()
答案 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.about
或duck.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)
你可以这样写,因为你已经定义了一个全局变量bill
和tail
,这里引用了它。
...
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')
所以这不符合你的想法。如果您想引用当前对象的bill
和tail
属性, 不能忽略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
并存储在实例中的tail
和Duck()
个对象,您始终需要使用self.bill
和{{1 }}