2013-10-12 2 views
-2

Как это метод __str__ в первом примере, возвращает строку успешно, когда self.foo не был определен:эффектов конструктора класса на его атрибутах

class foo: 
    foo = 'K-Dawg' 

    def __str__(self): 
     return self.foo 

obj = foo() 
print obj 
#K-Dawg 

И когда я создаю метод конструктора класса __init__, Это дает:

AttributeError: foo instance has no attribute 'foo'

class foo: 
    def __init__(self): 
     foo = 'K-Dawg' 

    def __str__(self): 
     return self.foo 

obj = foo() 
print obj 

Почему self.foo успешно возвращен в первом примере, а не во втором?

Какое влияние имеет конструктор класса на его атрибуты?

EDIT: Я знаю, что изменение foo = 'K-Dawg' к self.foo = 'K-Dawg'напечатает K-Dawg успешно, но что я спрашиваю, почему это атрибут foo в первом примере получает быть вызвана с помощью self.foo

+0

Только на боковой ноте '__init__' не является конструктором. – Hyperboreus

ответ

6

Модифицированных первая программа

class foo: 
    foo = 'K-Dawg' 

    def __str__(self): 
     print dir(self) 
     return self.foo 

obj = foo() 
print obj 

Модифицированных второй программы

class foo: 
    def __init__(self): 
     print locals() 
     foo = 'K-Dawg' 
     print locals() 

    def __str__(self): 
     print locals() 
     return self.foo 

obj = foo() 
print obj 

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

Первая программа напечатает

['__doc__', '__module__', '__str__', 'foo'] 
K-Dawg 

Мы можем видеть, что foo уже есть в объекте. Фактически, в этом случае foo является переменной класса (ничего не связано с экземплярами класса. Если вы находитесь на фоне C, C++ или JAVA, это можно рассматривать как статическую переменную, привязанную к классу не к объекту.)

Вторая программа напечатает

{'self': <__main__.foo instance at 0x7f528aa90488>} 
{'self': <__main__.foo instance at 0x7f528aa90488>, 'foo': 'K-Dawg'} 
{'self': <__main__.foo instance at 0x7f11f236d488>} 
AttributeError: foo instance has no attribute 'foo' 

это наглядно показывает нам, что переменная foo был создан в функции __init__ но не доступен, когда он достигает __str__. Это означает, что переменная foo, созданная в __init__, является локальной для этой функции.

Если вы хотите создать переменную в объекте, вы должны сделать что-то вроде этого

class foo: 
    def __init__(self): 
     print locals() 
     self.foo = 'K-Dawg' # Note the self keyword at the beginning 
     print locals() 

    def __str__(self): 
     print locals() 
     return self.foo 

obj = foo() 
print obj 

Выход

{'self': <__main__.foo instance at 0x7fe0e2da24d0>} 
{'self': <__main__.foo instance at 0x7fe0e2da24d0>} 
{'self': <__main__.foo instance at 0x7fe0e2da24d0>} 
K-Dawg 

self указывает на текущий экземпляр класса и мы добавив переменную, называемую foo, выполнив self.foo = 'K-Dawg'. Вот почему это работает.

2

В первом примере вы создали атрибут класса foo --- один атрибут, общий для всех экземпляров класса. Когда вы пытаетесь получить доступ к self.foo, если экземпляр не имеет собственного атрибута foo, он читает одно из этого класса.

Во втором случае вы вообще не создаете атрибут. foo в __init__ - это только локальная переменная. Если вы хотите создать переменный экземпляр вам нужно:

def __init__(self): 
    self.foo = 'K-Dawg' 
Смежные вопросы