using an instance of Object as an empty class

A

AlienBaby

Hi,

I'm just wondering why something is so, and whats going on under the
hood.

Now and again I use something like

class empty(object):
pass


simply so I can make an instance, and set some attributes on it.

a=empty()
a.whatever=something


Poking around with this, I assumed I could instead say

a=object()
a.whatever=something

but I get an attribute error. 'object object has no attribute
whatever'

I tried setattr() but get the same result.


So, it seems to me there is something special about instances of
object, and making an empty class that inherits from object, or
creating an instance of that class, is doing some 'magic' somewhere
that enables setting attributes etc..

Whats actually going on here, and why?

Matt.
 
P

Peter Otten

AlienBaby said:
I'm just wondering why something is so, and whats going on under the
hood.

Now and again I use something like

class empty(object):
pass


simply so I can make an instance, and set some attributes on it.

a=empty()
a.whatever=something


Poking around with this, I assumed I could instead say

a=object()
a.whatever=something

but I get an attribute error. 'object object has no attribute
whatever'

I tried setattr() but get the same result.


So, it seems to me there is something special about instances of
object, and making an empty class that inherits from object, or
creating an instance of that class, is doing some 'magic' somewhere
that enables setting attributes etc..

Whats actually going on here, and why?

Normal instances in Python store the contents in a dictionary called
__dict__.

a.attribute = 42

is then syntactic sugar for

a.__dict__["attribute"] = 42

As object serves as the base class for classes that don't have a __dict__,
usually to save memory, it cannot have a __dict__ either. Examples for
classes that don't accept attributes are builtins like int, tuple, and --
obviously -- dict. You can make your own using the __slot__ mechanism:
.... __slots__ = ["x", "y"]
....Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'z'
 
U

Ulrich Eckhardt

Peter said:
Examples for classes that don't accept attributes are builtins
like int, tuple, and -- obviously -- dict. You can make your own
using the __slot__ mechanism:
... __slots__ = ["x", "y"]
...Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'z'

Wow. This is something I've been missing dearly in my toolbox until now!
Typically, when in C++ I would have used a struct, I always created a class
that set the according attributes in the init function instead, which is
quite a bit more cumbersome. Or I used a tuple and hoped to get the position
of the elements correct.

Now, follow-up question:
1. The slots are initialized to None, right? Or are they just reserved? IOW,
would "print a.x" right after creation of the object print anything or raise
an AttributeError?

2. Is there a convenient syntax to init an instance of such a class? Can I
convert it from e.g. a dict or do I still have to write a constructor or
manually fill in the slots?


Thank you!


Uli
 
P

Peter Otten

Ulrich said:
Peter said:
Examples for classes that don't accept attributes are builtins
like int, tuple, and -- obviously -- dict. You can make your own
using the __slot__ mechanism:
class A(object):
... __slots__ = ["x", "y"]
...
a = A()
a.x = 42
a.y = "yadda"
a.z = 123
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'z'

Wow. This is something I've been missing dearly in my toolbox until now!
Typically, when in C++ I would have used a struct, I always created a
class that set the according attributes in the init function instead,
which is quite a bit more cumbersome. Or I used a tuple and hoped to get
the position of the elements correct.

Now, follow-up question:
1. The slots are initialized to None, right? Or are they just reserved?
IOW, would "print a.x" right after creation of the object print anything
or raise an AttributeError?

2. Is there a convenient syntax to init an instance of such a class? Can I
convert it from e.g. a dict or do I still have to write a constructor or
manually fill in the slots?

collections.namedtuple is a convenient struct replacement -- if you don't
mind that it is immutable.
 
S

steve+comp.lang.python

Ulrich said:
Peter said:
Examples for classes that don't accept attributes are builtins
like int, tuple, and -- obviously -- dict. You can make your own
using the __slot__ mechanism:
class A(object):
... __slots__ = ["x", "y"]
...
a = A()
a.x = 42
a.y = "yadda"
a.z = 123
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'z'

Wow. This is something I've been missing dearly in my toolbox until now!
Typically, when in C++ I would have used a struct, I always created a
class that set the according attributes in the init function instead,
which is quite a bit more cumbersome. Or I used a tuple and hoped to get
the position of the elements correct.

Often, the right solution for that is to use collections.namedtuple:
struct(x=2, y=3, z=0, spam='tasty', ham='', cheese=None)

namedtuple is available starting in Python 2.6.

This is not quite a struct, because it is immutable like all tuples. So
while you can access fields either by position or name:
3

you can't modify them. This is usually a feature.

__slots__ are generally considered the wrong solution. They were added to
the language purely as an optimization for cases where you need huge
numbers of objects and the space required by all the instance.__dict__ was
prohibitive. Unfortunately, __slots__ don't play well with various other
aspects of Python (e.g. inheritance), see Christian's earlier post for more
details. But if you can live with the limits of __slots__, perhaps it will
work for you.
 
U

Ulrich Eckhardt

Peter said:
collections.namedtuple is a convenient struct replacement -- if you don't
mind that it is immutable.

Thanks you and also Steven for mentioning this, it is an even better
replacement for what I had in mind!

Uli
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top