Найти - Пользователи
Полная версия: Ошибка инициализации класса
Начало » Python для новичков » Ошибка инициализации класса
1
caufman
Кажется я чего то не понимаю в объявлении классов. Вот имею вот такой код, который сбоит при инициализации класса 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'
Singularity
caufman
Расширения методов класса делают не так
http://stackoverflow.com/questions/576169/understanding-python-super-and-init-methods

http://stackoverflow.com/questions/12701206/how-to-extend-python-class-init
py.user.next
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'
>>>
john123
Кажется Вы немного запутались с наследованием в ООП и в частности с наследованием классов в 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 как правило используется, когда Вам нужно вернуть какое-то значение, либо оборвать выполнение функции в каком-то месте. Во всех остальных случаях ставить его нет смысла.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB