Dictless classes

  • Thread starter Steven D'Aprano
  • Start date
S

Steven D'Aprano

You can create instances without a __dict__ by setting __slots__:

py> class Dictless:
.... __slots__ = ['a', 'b', 'c']
....
py> Dictless().__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Dictless' object has no attribute '__dict__'


But the class itself still has a __dict__:

py> Dictless.__dict__
dict_proxy({'a': <member 'a' of 'Dictless' objects>, 'c': <member 'c' of
'Dictless' objects>, 'b': <member 'b' of 'Dictless' objects>,
'__module__': '__main__', '__slots__': ['a', 'b', 'c'], '__doc__': None})


I wonder whether there is some metaclass magic one can do to create a
class without a __dict__?


I don't have a use-case for this. But I have some code which assumes that
every class will have a __dict__, and I wonder whether that is a safe
assumption.
 
A

alex23

R

Roy Smith

Duncan Booth said:
Also you cannot create a subclass of 'type' with non-empty slots (it throws
a type error "nonempty __slots__ not supported for subtype of 'type'").
However I don't think that's really relevant as even if they did allow you
to use __slots__ it wouldn't prevent the creation of a __dict__ for the
'type' base class.

I played around a bit trying to write a metaclass which implemented:

def __getattribute__(self, name):
if name == "__dict__":
raise AttributeError

but didn't get very far. Maybe somebody with stronger metaclass-fu than
I have could run with this idea?
 
T

Terry Reedy

You can create instances without a __dict__ by setting __slots__:

Each *instance* does not have its own dict because each would be equal,
therefore only one hidden mapping is needed, somewhere. But attribute
names must be mapped to objects somehow.
I wonder whether there is some metaclass magic one can do to create a
class without a __dict__?

If every 'class' instance of the metaclass has the same attributes, then
it would not be necessary for each 'class' to have its individual dict.
But would you call such things 'classes'?
I don't have a use-case for this. But I have some code which assumes
that every class will have a __dict__, and I wonder whether that is a
safe assumption.

It depends what you mean by a class. A 'metaclass' is just a callable
that accepts 3 args. The only constraint appears that its return must be
callable (and accept at least one arg).

class M():
__slots__ = ()
def __init__(*args): pass
def __call__(*args): pass

class C(metaclass = M): pass

c=C()
print(type(C), C, c, hasattr(C, '__dict__'))

#
<class '__main__.M'> <__main__.M object at 0x000000000220A1C0> None False

Is C a dictless class? Your choice ;-).

Actually, Python thinks not. If we add
class Mclassob(object): pass
and have __call__ return an instance thereof and try
c.__class__ = C
we get
TypeError: __class__ must be set to a class, not 'M' object
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,983
Messages
2,570,187
Members
46,747
Latest member
jojoBizaroo

Latest Threads

Top