Одна очень важная вещь, чтобы быть в курсе - если эти атрибуты остаются в классе, __slots__
поколение будет бесполезно ... ну, может быть, не бесполезно - это сделает атрибуты класса чтения -только; вероятно, не то, что вы хотите.
Легкий способ сказать: «Хорошо, я инициализирую их никому, а затем пусть они исчезнут». Отлично! Вот один из способов сделать это:
class B(object):
three = None
four = None
temp = vars() # get the local namespace as a dict()
__slots__ = temp.keys() # put their names into __slots__
__slots__.remove('temp') # remove non-__slots__ names
__slots__.remove('__module__') # now remove the names from the local
for name in __slots__: # namespace so we don't get read-only
del temp[name] # class attributes
del temp # and get rid of temp
Если вы хотите сохранить эти начальные значения она занимает немного больше работы ... вот один из возможных решений:
class B(object):
three = 3
four = 4
def __init__(self):
for key, value in self.__init__.defaults.items():
setattr(self, key, value)
temp = vars()
__slots__ = temp.keys()
__slots__.remove('temp')
__slots__.remove('__module__')
__slots__.remove('__init__')
__init__.defaults = dict()
for name in __slots__:
__init__.defaults[name] = temp[name]
del temp[name]
del temp
Как вы можете видеть, это возможно сделать это без метакласса - но кто хочет все, что шаблон? Метакласс определенно может помочь нам очистить это:
class MakeSlots(type):
def __new__(cls, name, bases, attrs):
new_attrs = {}
new_attrs['__slots__'] = slots = attrs.keys()
slots.remove('__module__')
slots.remove('__metaclass__')
new_attrs['__weakref__'] = None
new_attrs['__init__'] = init = new_init
init.defaults = dict()
for name in slots:
init.defaults[name] = attrs[name]
return super(MakeSlots, cls).__new__(cls, name, bases, new_attrs)
def new_init(self):
for key, value in self.__init__.defaults.items():
setattr(self, key, value)
class A(object):
__metaclass__ = MakeSlots
one = 1
two = 2
class B(object):
__metaclass__ = MakeSlots
three = 3
four = 4
Теперь все занудство хранится в метаклассе, и фактический класс легко читать и (надеюсь!) Понять.
Если у вас есть что-то еще в этих классах помимо атрибутов, я настоятельно рекомендую вам поставить все, что есть в классе mixin - их непосредственное включение в конечный класс еще более усложнит метаклассу.
Это запах преждевременной оптимизации. Можете ли вы обсудить свой вариант использования немного больше? – SingleNegationElimination
Это не имеет большого значения - атрибуты уже определены динамически во время выполнения. Зачем возиться с __slots__? Что вы планируете делать с __slots__? –
Я сделал нагрузку профилирования и есть место для улучшения дизайна, который я думаю. Для 100 000 экземпляров класса я хочу удалить возможность динамически определяемых атрибутов, чтобы классы были более легкими. – Dan