Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #24804 > unrolled thread
| Started by | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| First post | 2012-07-03 05:03 +0000 |
| Last post | 2012-07-03 19:25 -0400 |
| Articles | 5 — 5 participants |
Back to article view | Back to comp.lang.python
Dictless classes Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-03 05:03 +0000
Re: Dictless classes alex23 <wuwei23@gmail.com> - 2012-07-02 22:50 -0700
Re: Dictless classes Duncan Booth <duncan.booth@invalid.invalid> - 2012-07-03 09:38 +0000
Re: Dictless classes Roy Smith <roy@panix.com> - 2012-07-03 08:28 -0400
Re: Dictless classes Terry Reedy <tjreedy@udel.edu> - 2012-07-03 19:25 -0400
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2012-07-03 05:03 +0000 |
| Subject | Dictless classes |
| Message-ID | <4ff27d28$0$11103$c3e8da3@news.astraweb.com> |
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.
--
Steven
[toc] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2012-07-02 22:50 -0700 |
| Message-ID | <6a9a2166-db2f-4af1-a4be-d2f1e327fa4a@d6g2000pbt.googlegroups.com> |
| In reply to | #24804 |
On Jul 3, 3:03 pm, Steven D'Aprano <steve +comp.lang.pyt...@pearwood.info> wrote: > 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. Remember the recent thread on using a different implementation for <object>.__dict__? https://groups.google.com/group/python-ideas/browse_frm/thread/f15ef3c7b702a1fa Given it was impossible to have it *not* create a conventional dict via metaclasses, I would assume that there will always be a .__dict__.
[toc] | [prev] | [next] | [standalone]
| From | Duncan Booth <duncan.booth@invalid.invalid> |
|---|---|
| Date | 2012-07-03 09:38 +0000 |
| Message-ID | <XnsA0856B054AB3Fduncanbooth@127.0.0.1> |
| In reply to | #24804 |
Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: > You can create instances without a __dict__ by setting __slots__: That is a necessary but not a sufficient condition. An instance of a class can be created without a dict only if (either you set __slots__ or you implement it in C without a __dict__ attribute) AND none of its base classes require a dict. Setting __slots__ when a base class requires that its instances have a __dict__ doesn't prevent creation of the __dict__. > > But the class itself still has a __dict__: The class is an instance of 'type'. Instances of 'type' require a dict therefore every class requires a dict. Except of course for old style classes in Python 2.x but they have a __dict__ too. 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 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. I believe so. -- Duncan Booth http://kupuguy.blogspot.com
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2012-07-03 08:28 -0400 |
| Message-ID | <roy-3F5730.08280003072012@news.panix.com> |
| In reply to | #24811 |
In article <XnsA0856B054AB3Fduncanbooth@127.0.0.1>,
Duncan Booth <duncan.booth@invalid.invalid> wrote:
> 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?
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2012-07-03 19:25 -0400 |
| Message-ID | <mailman.1767.1341357962.4697.python-list@python.org> |
| In reply to | #24804 |
On 7/3/2012 1:03 AM, Steven D'Aprano wrote:
> 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
--
Terry Jan Reedy
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web