添加__slots __

时间:2017-01-06 22:04:59

标签: python properties slots

如何让广告位与@property一起使用以下课程。我有几千个以下类的实例导致内存问题,所以我添加了插槽

我使用数据创建了实例,然后稍后将位置信息添加到实例中。

添加广告位后,我的实例创建无效,我收到以下错误

属性错误:'主持人'对象没有属性' _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)

2 个答案:

答案 0 :(得分:2)

__slots__通过在类上创建可直接访问实例的内存数据结构的描述符来工作。您正在使用location对象屏蔽property描述符,并且您定义了属性_location,而不是在插槽中。

设置_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)

答案 1 :(得分: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()