2013-12-22 1 views
2

У меня есть эти два класса:функция не переопределен в дочернем классе

class Shape(object): 
    def __init__(self, start_point, *args): 
     self.vertices = [] 
     self.__make_vertices(start_point, *args) 

    def __make_vertices(self, start_point, *args): 
     print "Not Implemented: __make_vertices" 

    def __getitem__(self, *args): 
     return self.vertices.__getitem__(*args) 

class Cube(Shape): 
    def __init__(self, start_point, side_length): 
     Shape.__init__(self, start_point, side_length) 

    def __make_vertices(self, start_point, side_length): 
     append = self.vertices.append 
     start_point = Vector(*(start_point)) 
     i, j, k = side_length*I, side_length*J, side_length*K 
     append(start_point) 
     append(self.vertices[-1] - k) 
     append(self.vertices[-1] - j) 
     append(self.vertices[-1] + k) 
     append(self.vertices[-1] - i) 
     append(self.vertices[-1] - k) 
     append(self.vertices[-1] + j) 
     append(self.vertices[-1] + k) 
     print self.vertices 

Когда я делаю новый Cube, я ожидал, что функция __make_vertices я определил в классе Cube будет называться, но вместо этого я продолжаю получение сообщения о том, что Shape классы __make_vertices функция распечатывается. Что я недопонимаю?

+0

http://php.net/manual/en/language.oop5.overloading.php –

+0

@Allendar: Это Python, а не PHP. – BrenBarn

+0

Извините, я засыпаю за ноутбуком, хе-хе, мой плохой :) –

ответ

7

Вы отсутствуете name mangling:

Любой идентификатор вида __spam (по крайней мере, два ведущие подчеркиваний, не более одного знак подчеркивания) текстуально заменяются _classname__spam, где имя_класс является текущим именем класса с ведущим подчеркиванием (ы) разделены. Это манипулирование выполняется независимо от синтаксического положения идентификатора, если оно встречается в определении класса.

Другими словами, вы должны использовать только имена атрибутов/метод начинается с двух символов подчеркивания, когда вы специально не хотят подклассы, чтобы переопределить их, а скорее обеспечить их собственный вариант из них. Это редко, поэтому обычно вам не нужно использовать имена с двойным подчеркиванием.

+1

Обычно люди связывают два ведущих символа подчеркивания с * частным * членами и одно ведущее подчеркивание с * защищенными * (или другими внутренними) членами. Поэтому, если вы хотите разрешить переопределение, используйте максимум одно подчеркивание. – poke

+0

@poke: Это похоже на правду, но по многим причинам люди думают, что хотят, чтобы частные/защищенные атрибуты на самом деле не были действительны в Python. Использование одиночных подчеркиваний не является механизмом контроля доступа, это соглашение о документации о том, какие методы можно использовать как часть API, ориентированного на внешнюю сторону. Даже использование методов с двойным подчеркиванием не препятствует доступу, оно просто меняет имя. Поэтому я не хочу использовать эти термины, потому что они могут запутать людей в попытке использовать синтаксис для получения возможностей скрытия доступа, которые на самом деле не существуют в Python. – BrenBarn

+0

Лучший способ делать частные методы - это не определять метод внутри класса вообще! Вместо этого, есть функция в том же пакете, который передается все необходимое для выполнения действия, то есть 'def_private_foo (obj, arg1, arg2, ...)'. – wheaties

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