2017-02-06 8 views
1
class Ant: 
    count = 0 

    def __init__(self): 
     if count == 0: 
      self.real = True 
     else: 
      self.real = False 
     count += 1 

Итак, в основном, чего я хочу достичь, я хочу, чтобы только первый экземпляр этого класса имел атрибут «настоящий», который должен быть True, а последующие атрибуты - False. Я знаю, что сейчас это даст мне unboundlocal ошибку для count. Как это сделать?Как изменить атрибут класса внутри __init__?

+0

' count' inside '__init__' - обычная локальная переменная. Вам нужен 'Ant.count' для доступа к переменной уровня * * –

ответ

4

count Изменение Для Ant.count

count В является членом класса (разделяется между всеми экземплярами класса Ant) и не относится к конкретному экземпляру вы должны использовать его с префиксом имени класса.

class Ant: 
    count = 0 

    def __init__(self): 
     if Ant.count == 0: 
      self.real = True 
     else: 
      self.real = False 
     Ant.count += 1 
+0

' self.count' также будет работать и не требует жесткого кодирования имени класса в функции (поэтому его не нужно исправлять, если classname было изменено). – martineau

+2

@martineau Нет, self.count будет переменной экземпляра - это очень конкретно _not_, чего хочет OP. Им нужна переменная класса, поэтому Ant.count - это (возможно, только) правильный способ ее ссылки. – barny

+1

Ой, да, вы правы.'self' работает только для чтения значения переменной класса, а не для его изменения, что создаст переменную экземпляра в качестве побочного эффекта (и затем скрыть атрибут класса). Тем не менее, по-прежнему можно избежать жесткого кодирования имени класса по всему месту в коде, используя вместо него 'self .__ class__'. Если это слишком долго, локальная переменная может быть создана в начале метода с помощью 'cls = self .__ class__' и используется внутри. – martineau

1

предпочитает использовать self.__class__.variable - если вы не хотите то же переменное для совместного использования всех подклассов.

В коде так:

class Ant: 
    count = 0 

значение "счетчик" хранится в классе __dict__ атрибута. Если вы делаете что-то вроде:

class Ant: 
    count = 0 
    def __init__(self): 
     print(self.count) 

Механизма доступа attrobute, определенного в модели данных в Python будет видеть не экземпляр count в инстанции «Я», и получить значение из своего класса. Итак, если вы указали значение переменной класса, вы можете использовать его как обычный экземпляр.

Однако, если ваш код выглядит:

def __init__(self): 
    self.count += 1 

Что происходит Ins целую разные вещи: Python Читает атрибут из класса, как указано выше, добавляет к нему 1, и сохраняет новый результат экземпляр.

Таким образом, всякий раз, когда вы хотите получить доступ к значению класса, вы можете жестко закодировать имя класса - (так как, когда код методы выполняется, класс уже создан и «известный»):

class Ant: 
    count = 0 
    def __init__(self): 
     Ant.count += 1 

Или, еще лучше, используйте __class__ атрибут экземпляра - таким образом, вы всегда будете получить значение переменной для надлежащего подкласса

class Ant: 
    count = 0 
    def __init__(self): 
     self.__class__.count += 1 

class FireAnt(Ant): 
    count = 0 

(Обратите внимание, что, как и во втором примере выше, если подкласс не содержит собственный count переменная, значение от суперкласс «count будет прочитан, новый будет создан в подклассе при первом запуске этого кода)