2010-06-16 4 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 

Почему мне нужно объявить х и у, когда я могу сделать это:

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

Я надеюсь, что я быть ясно ...

Спасибо за ваше время.

+4

@ Вы должны задать два отдельных вопроса. – systempuntoout

+0

@ Andy: Какой учебник вы используете? Укажите название или ссылку. –

+1

@ S.Lott: Учебники Python на своем веб-сайте. – Andy

ответ

2

Ссылка на экземпляр в Python является явной. Таким образом, это можно манипулировать, например, декораторов, прежде чем, наконец, перейти к методу.

Мы должны объявить x и y как аргументы функции, чтобы мы могли использовать их имена внутри функции, связанные с аргументами, переданными в соответствующем вызове функции.

+0

Предположим, если у меня есть атрибут, который я не хочу создавать немедленно, это нормально, если я это сделаю: def __init __ (self, x): try: self.y = foo // сделать что-то здесь за исключением: Если условие не выполнено, не создавайте его – Andy

+0

Конечно, но это должно быть глобальным. И не используйте голые, кроме. –

+0

Ничто в этом не делает 'y' зависимым от' x' ... –

0
  1. В Python методы всегда должны принимать «один дополнительный» аргумент, который является ссылкой на экземпляр, на который вызывается метод. Это автоматически на других языках, таких как Java, C# и т. Д., Но Python многословен.

  2. Это не имеет смысла. Где x и y в этом примере? Если вы хотите, чтобы конструктор принял два аргумента, которые заполняют объект, определите его как таковой. В противном случае вы делаете что-то еще.

0

Python отличается от языков, таких как C++ и Java, тем, что ссылка на экземпляр объекта передается явно.

То есть, если у вас есть объект, являющийся экземпляром класса, и вы хотите вызвать метод, который работает на этом экземпляре (например, читает его поля), вы используете саморесурсы как объект.

В C++ и Java у вас есть неявная «эта» ссылка, которая присутствует в скомпилированной версии вашей программы, но не в исходном коде. Вы используете статическое ключевое слово, чтобы превратить его в метод класса, у которого нет «этого».

1

Просто чтобы быть ясно

Почему я должен объявить х и у, когда я могу это сделать:

def __init__(self): 
    self.x = x 
    self.y = 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 Vars х и у (это они есть) к экземпляру

с:

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

присвоить то, что вы даете в качестве параметра конструктору

и что является гораздо более гибким :-)

+0

Спасибо. Гораздо яснее. – Andy

1

само это название «магия» - это действительно может быть что угодно, но само это используется для согласованности и ясности. Чтобы ответить на ваш вопрос, каждый метод/функция класса требует явной ссылки на класс в качестве первого параметра. Использование 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> 

Ваш второй пример не будет реально работать, если у вас уже есть х и у в пространстве имен.

Например, если вы определили свой класс:

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

+0

'' self'' - это, безусловно, не волшебное имя: это просто имя, принятое по соглашению. – krawyoti

+0

«Я» не является магическим из-за букв, из которых он состоит, но из-за того, где он появляется. '' –

Смежные вопросы