2015-04-17 2 views
0

Вот то, что я пытался в Python (2.7.9) оболочки (IDLE на Windows):Добавление переменной-члена унаследованного класса в Python

>>> class A: 
    def bob(self, x): 
     self.val = x*x 

следуют:

>>> class B(A): 
     def bob(self,x): 
      flow = x*x*x 
      A.bob(self, x) 

, а затем :

>>> y = B() 
>>> y.bob(4) 
>>> y.val 
16 
>>> y.flow 

Traceback (most recent call last): 
    File "<pyshell#52>", line 1, in <module> 
    y.flow 
AttributeError: B instance has no attribute 'flow' 

Вопрос в том, почему метод flow() не определен? Оглядываясь, у меня сложилось впечатление, что, возможно, переменная-член может быть инициализирована в init() во время фазы строительства объекта, но это тоже не помогло.

+0

Кстати, вопрос, который вы написали буквально, - «почему метод flow() не определен». На что он жалуется, что _attribute_ 'flow' не существует. И я уверен, что вы ожидали нормального атрибута данных (переменная, ссылающаяся на число 64), а не на метод, верно? – abarnert

ответ

3

flow сама по себе является лишь локальная переменная, которая живет до тех пор, как этот метод, а затем уходит.

self.flow - это переменная экземпляра. Это то, что вы хотели.

(Если вы пришли из другого языка, как C++, который имеет неявный this/self для членов ... Python не имеет этого. Guido explains why, даже с некоторыми умными идеями, которые делают исторические причины уже не актуально, Python по-прежнему не имеет этого, и, вероятно, никогда не будет.)


в качестве примечания, в Python 2.7, всегда использовать class A(object):, не class A:. В противном случае вы создаете классы старого стиля. Это не делает разницы в этом случае, но в тех случаях, когда делает делает разницу, вы всегда хотите новое поведение. *


Оглядевшись, у меня сложилось впечатление, что, возможно, переменная-член может быть инициализирована в init() во время фазы построения объекта, но это тоже не помогло.

Ну, во-первых, это __init__; метод, называемый только init, не будет вызван во время построения объекта.

В любом случае, обычно вы хотите, чтобы создать все свои атрибуты в __init__. (Это один из простых способов гарантировать, что все экземпляры вашего типа будут иметь этих членов, если только вы не найдете их del, конечно ...) Но ничего нет , требующих вам. В Python, вы можете добавлять и удалять атрибуты объекта в любой момент времени. **


* Есть некоторые случаи, когда, возможно, вы этого не делаете, но если вы уже не знаете, эти случаи и как для оценки этих аргументов они не применяются к вам.

** Если класс не мешает вам это сделать. Множество встроенных типов; вы можете сделать что-то подобное себе с __slots__; или вы даже можете написать собственный метод __setattr__, который сделает все, что вы хотите.

+0

Спасибо за разъяснение, абсолютно ясно. – icarus74

4

вы не назначая поток для экземпляра класса

class B(A): 
    def bob(self,x): 
     flow = x*x*x # should be self.flow 
     A.bob(self, x) 

more on scoping

+0

Получил, спасибо. – icarus74

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