Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 25, 2014 20:24:25

caufman
Зарегистрирован: 2013-02-15
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Ошибка инициализации класса

Кажется я чего то не понимаю в объявлении классов. Вот имею вот такой код, который сбоит при инициализации класса Label на строке self.plane = Plane.__init__(self, …). Самое странное, что ошибка - несуществование объекта в self.plane. При попытке вывода этого атритбута, получаю None <class ‘NoneType’>, тогда как при создании экзепляра из того же класса в теле самого скрипта выдает <__main__.Plane object at 0x02BD9DB0> <class ‘__main__.Plane’>. Можете объяснить, в чем разница между этими вызовами?
Текст ошибки:

Traceback (most recent call last):
  File "game.py", line 96, in <module>
    lab.draw()
  File "game.py", line 68, in draw
    self.plane.draw()
AttributeError: 'NoneType' object has no attribute 'draw'

Офлайн

#2 Июнь 25, 2014 21:04:44

Singularity
Зарегистрирован: 2011-07-28
Сообщения: 1387
Репутация: +  75  -
Профиль   Отправить e-mail  

Ошибка инициализации класса

caufman
Расширения методов класса делают не так
http://stackoverflow.com/questions/576169/understanding-python-super-and-init-methods

http://stackoverflow.com/questions/12701206/how-to-extend-python-class-init

Отредактировано Singularity (Июнь 25, 2014 21:09:23)

Офлайн

#3 Июнь 25, 2014 22:16:09

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9879
Репутация: +  853  -
Профиль   Отправить e-mail  

Ошибка инициализации класса

caufman
Самое странное, что ошибка - несуществование объекта в self.plane. При попытке вывода этого атритбута, получаю None <class ‘NoneType’>

Это значит, что объект существует, и его значение равно None.
Метод __init__ и не может ничего возвращать.

>>> class A:
...     def __init__(self):
...         return 1
... 
>>> a = A()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() should return None, not 'int'
>>>



Офлайн

#4 Июнь 25, 2014 22:18:09

john123
Зарегистрирован: 2013-12-22
Сообщения: 56
Репутация: +  7  -
Профиль   Отправить e-mail  

Ошибка инициализации класса

Кажется Вы немного запутались с наследованием в ООП и в частности с наследованием классов в Python.

Класс Label у Вас унаследован от класса Plane, а это значит, что все поля и методы класса Plane, также доступны и в Label.

Однако в классе Label вы переопределяете конструктор __init__ и метод draw(), которые Вам предоставляет класс Plane.
Это означает, что при создании объекта класса Label (lab = Label()) при вызове конструктора и метода draw() (lab.draw()) у Вас будут вызываться только методы из Вашего класса Label.

Если же Вы хотите в классе Label в какой-то момент времени вызвать родительские методы класса Plane, то Вам необходимо воспользоваться ф-цией super(), либо вызывать метод напрямую (но это не очень гибкий подход):

class Label(Plane):
    def __init__(self, param1, param2, param3, param4):
        super(Label, self).__init__(param1, param2, param3)
        self.my_param4 = param4
    def draw():
        doSomeActions()
        super(Label, self).draw()

Причем в момент вызова super(), фактически происходит вызов методов родительского класса. Т.е. считайте, что заместо super(Label, self).draw() происходит вызов Plane.draw(self).

Если же Вы не используете super(), то Вы, по сути, полностью переопределяете метод родительского класса своим методом.

В общем почитайте про наследование классов в ООП, про то, что такое self в Python классах и про ф-цию super() и будет Вам счастье

И еще замечание по коду - совершенно не обязательно проставлять в каждой ф-ции оператор return. Return как правило используется, когда Вам нужно вернуть какое-то значение, либо оборвать выполнение функции в каком-то месте. Во всех остальных случаях ставить его нет смысла.

Отредактировано john123 (Июнь 25, 2014 22:24:53)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version