2017-01-06 2 views
1

Как я могу получить слоты для работы с @property для класса ниже. У меня несколько тысяч экземпляров класса ниже, что вызывает проблемы с памятью, поэтому я добавил слоты@property не работает после добавления __slots__

Я создал экземпляры с данными, а затем добавил данные о местоположении позже в экземпляры.

После добавления слотов мое создание экземпляра не работает, и я получаю следующую ошибку

AttributeError: «Хост» объект не имеет атрибута «_location»

class Host(object): 
    __slots__ = ['data', 'location'] 

    def __init__(self, data, location=''): 
     self.data = data 
     self.location = location 

    @property 
    def location(self): 
     return self._location 

    @location.setter 
    def location(self, value): 
     self._location = value.lower() 

    def __repr__(self): 
     if self.location == '': 
      self.loc = 'Not Found' 
     else: 
      self.loc = self.location 
     return 'Host(name={}, location={})'.format(self.name, self.loc) 
+1

Поскольку вы не указываете атрибут поддержки '_location' в' __slots__'. Сообщение об ошибке сообщает об этом. – jonrsharpe

+0

Почему '_location' и' loc' также не входят в слоты? – Eric

+0

Что такое 'self.name', которое должно быть в' __repr__'? –

ответ

2

__slots__ работает путем создания дескрипторов на классе, который имеет прямой доступ к структуре данных в памяти вашего экземпляра. Вы маскируете дескриптор location своим объектом property, и вы определили новый атрибут _location, который не находится в слотах.

Make _location слот (как это атрибут, который вы на самом деле хранения):

class Host(object): 
    __slots__ = ['data', '_location'] 

Свойство location (также объект дескриптора) может затем правильно назначить self._location, атрибут подкрепленную дескриптора слота ,

Обратите внимание, что вы не необходимости использования self.loc в __repr__, просто сделать вместо этого локального переменной. Вы также пытаетесь использовать атрибут self.name, который не существует; не ясно, что значение, которое должно быть, однако:

def __repr__(self): 
    loc = self.location or 'Not Found' 
    name = self.data['name'] # or some other expression 
    return 'Host(name={}, location={})'.format(name, loc) 
0

Определение для __slots__ должно иметь название основных атрибутов, которые будут хранить данные, на которые ссылаются свойствами. В приведенном ниже примере name mangling вызывается для переменных, к которым не следует обращаться за пределами класса. Код похож на ваш и не имеет ошибок в соответствии с веб-сайтом PEP8 online.

#! /usr/bin/env python3 
def main(): 
    print(Host('Hello, world!', 'Earth')) 
    print(Host('Hello, Xyz!')) 


class Host: 

    __slots__ = '__name', '__location' 

    def __init__(self, name, location=''): 
     self.name = name 
     self.location = location 

    def __repr__(self): 
     return '{!s}({!r}, {!r})'.format(
      type(self).__name__, 
      self.name, 
      self.location 
     ) 

    @property 
    def name(self): 
     return self.__name 

    @name.setter 
    def name(self, value): 
     self.__name = value 

    @property 
    def location(self): 
     return self.__location 

    @location.setter 
    def location(self, value): 
     self.__location = value.casefold() if value else 'Not Found' 


if __name__ == '__main__': 
    main() 
Смежные вопросы