Eine sehr wichtige Sache bewusst zu sein - wenn diese Attribute in der Klasse bleiben, die __slots__
Generation nutzlos sein wird ... okay, vielleicht nicht nutzlos - es wird die Klassenattribute machen lesen -nur; wahrscheinlich nicht was du willst.
Der einfache Weg ist zu sagen: "Okay, ich werde sie zu keiner initialisieren, dann lassen Sie sie verschwinden." Ausgezeichnet! Hier ist eine Möglichkeit das zu tun:
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
Wenn Sie wollen, dass diese Anfangswerte halten es ein bisschen mehr Arbeit nimmt ... hier ist eine mögliche Lösung:
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
Wie Sie sehen können, ist es möglich ohne Metaklasse - aber wer will das alles? Eine Metaklasse könnte uns auf jeden Fall helfen, diese nach oben zu reinigen:
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
Nun ist die ganze Langweiligkeit in den Metaklasse gehalten wird, und die tatsächliche Klasse ist einfach zu lesen und (hoffentlich) zu verstehen.
Wenn Sie außer den Attributen noch etwas anderes in diesen Klassen benötigen, empfehle ich Ihnen dringend, alles in eine Mixinklasse zu setzen - wenn Sie direkt in der letzten Klasse wären, würde das die Metaklasse noch komplizierter machen.
Dies riecht nach vorzeitigen Optimierung. Können Sie Ihren Anwendungsfall ein wenig mehr diskutieren? – SingleNegationElimination
Das ist nicht sehr sinnvoll - Attribute sind zur Laufzeit bereits dynamisch definiert. Warum sich mit __slots__ anlegen? Was hast du mit __slots__ vor? –
Ich habe eine Menge Profiling gemacht und es gibt Raum für Verbesserungen am Design, denke ich. Bei 100.000 Klasseninstanzen möchte ich die Fähigkeit zum dynamischen Definieren von Attributen entfernen, damit die Klassen leichter sind. – Dan