2010-06-16 61 views
3

我是新来的Python所以请不要火焰我,如果我问东西太多noobish :)关于Python类初级问题

1.

考虑我有一个类:

class Test: 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 
    def wow(): 
     print 5 * 5 

现在我尝试创建该类的对象:

x = Test(3, 4) 

这可按预期工作。然而,当我尝试调用该方法哇(),它返回一个错误,这是通过改变哇(固定):

def wow(self) 

为什么我需要包括self,如果我不这样做,有什么该方法的意思是?

2.在__init__定义:

def __init__(self, x, y): 
    self.x = x 
    self.y = y 

为什么我需要声明x和y,当我可以这样做:

def __init__(self): 
    self.x = x 
    self.y = y 

我希望我是清楚的...

感谢您的时间。

+4

@你应该问两个单独的问题。 – systempuntoout 2010-06-16 13:36:02

+0

@安迪:你正在使用哪个教程?请提供名称或链接。 – 2010-06-16 14:10:25

+1

@ S.Lott:在他们的网站上的Python教程。 – Andy 2010-06-16 14:17:37

回答

2

Python中的实例引用是显式的。这样它可以被例如最后传递给方法的装饰器。

我们需要声明xy作为函数的参数,以便我们可以在函数中使用它们的名称,并绑定到在相应函数调用中传递的参数。

+0

假设,如果我有一个属性,我不想立即实例化,是否可以,如果我这样做: def __init __(self,x): 尝试: self.y = foo //在这里做某事 除外: 如果条件不符合,请不要创建它 – Andy 2010-06-16 13:42:31

+0

当然,但它必须是全局的。并且不要使用除了。 – 2010-06-16 13:45:42

+0

什么都不会让'y'依赖于'x' ... – 2010-06-16 14:01:06

0
  1. 在Python中,方法应该总是带有“一个额外的”参数,它是对该方法被调用的实例的引用。这在其他语言(例如Java,C#等)中是自动的,但Python对此非常详细。

  2. 这没有意义。那个例子中的xy在哪里?如果你想让构造函数接受两个填充对象的参数,就像这样定义它。否则,你正在做其他事情。

0

Python与C++和Java等语言的不同之处在于对象实例引用是明确传递的。也就是说,如果你有一个对象是这个类的一个实例,并且你想调用一个对该实例进行操作的方法(例如,读取它的字段),那么你使用自引用作为对象。

在C++和Java中,您有一个隐含的“this”引用,它存在于您的程序的编译版本中,但不在源代码中。你使用static关键字将它变成一个没有“this”的类方法。

1

只是要清楚

为什么我需要声明x和y,当 我可以这样做:

def __init__(self): 
    self.x = x 
    self.y = y 

这^只会工作,如果X和Y在运行时找到 - 如果它们没有被传入,那么它们必须被设置在其他地方(全局),否则会产生错误。

>>> class c: 
    def __init__(self): 
     self.x = x 

>>> x = 1 
>>> q = c() 
>>> q.x 
1 
>>> del x 
>>> q.x 
1 
>>> w = c() 

Traceback (most recent call last): 
    File "<pyshell#24>", line 1, in <module> 
    w = c() 
    File "<pyshell#14>", line 3, in __init__ 
    self.x = x 
NameError: global name 'x' is not defined 
>>> 
>>> w = c(2) 

Traceback (most recent call last): 
    File "<pyshell#19>", line 1, in <module> 
    w = c(2) 
TypeError: __init__() takes exactly 1 argument (2 given) 

这就是为什么你想/需要指定它们作为参数传递 - 这可能与全球的查找工作,但它可能会违反“principle of least astonishment

4

如果你这样做:

def __init__(self): 
    self.x = x 
    self.y = y 

您分配gobal瓦尔x和y(它,他们存在)到您的实例

有:

def __init__(self, x, y): 
     self.x = x 
     self.y = y 

你分配你给什么作为参数的构造

,这是很多更灵活:-)

+0

谢谢。现在更清楚了。 – Andy 2010-06-16 13:48:58

1

自我是一个“神奇”的名字 - 它真的可以是任何东西,但self用于保持一致性和清晰度。为了回答你的问题,每个类方法/函数都需要显式引用该类作为第一个参数。使用Ipython

In [66]: class Test: 
    ....:  def __init__(self): 
    ....:   pass 
    ....:  def wow(self): 
    ....:   print self 
    ....: 
    ....: 

In [67]: x = Test() 

In [68]: x.wow() 
<__main__.Test instance at 0x0159FDF0> 

你的第二个例子中实际并不起作用,除非你已经在你的命名空间中的x和y。

举例来说,如果你定义的类:

class Test: 
    def __init__(self): 
     self.x = x 
     self.y = y 

,并试图

x = Test() 

它会抛出一个NameError

但是,如果你写:

x = 3 
y = 4 
test = Test() 

那么它会工作。但是,做这样的事情不是一个好主意。为什么读线2:

In [72]: import this 
The Zen of Python, by Tim Peters 

Beautiful is better than ugly. 
Explicit is better than implicit. 
Simple is better than complex. 
Complex is better than complicated. 
Flat is better than nested. 
Sparse is better than dense. 
Readability counts. 
Special cases aren't special enough to break the rules. 
Although practicality beats purity. 
Errors should never pass silently. 
Unless explicitly silenced. 
In the face of ambiguity, refuse the temptation to guess. 
There should be one-- and preferably only one --obvious way to do it. 
Although that way may not be obvious at first unless you're Dutch. 
Now is better than never. 
Although never is often better than *right* now. 
If the implementation is hard to explain, it's a bad idea. 
If the implementation is easy to explain, it may be a good idea. 
Namespaces are one honking great idea -- let's do more of those! 
+0

感谢这个答案:)真的! – Andy 2010-06-16 14:09:34

+0

'self''绝对不是一个神奇的名字:它简直就是一个习惯采用的名字。 – krawyoti 2010-06-16 14:21:19

+0

“自我”不是因为它包含的字母,而是因为它出现在哪里。 '' – 2010-06-16 15:14:24