Reputation: 61
If everything is object, then why won't the following code work:
x = 6
x.newAttrib = 8
So it's not an object, or some limited object?
Upvotes: 1
Views: 217
Reputation: 1125058
Yes, everything is an object. However, everything being an object does not mean that everything takes arbitrary attributes.
Integers in Python are objects, and have attributes and methods (which are just callable attributes):
>>> x = 6
>>> x.real
6
>>> x.imag
0
>>> x.bit_length()
3
To support arbitrary attributes, an object needs to have a __dict__
mapping. Integers don't have such a mapping:
>>> x.__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute '__dict__'
Other objects do, like functions, for example:
>>> def foo(): pass
...
>>> foo.__dict__
{}
>>> foo.bar = 'baz'
But a __dict__
mapping comes with a price: a larger memory footprint for such objects. Since Python uses a lot of integers, it makes sense to not give them a __dict__
mapping, to save memory. You very rarely would need to give them extra attributes anyway.
You can define your own classes that produce instances without a __dict__
attribute, by giving your class a __slots__
class variable; this defines the fixed attributes an instance supports. This lets you benefit from the same memory savings:
>>> class Demo(object):
... __slots__ = ('foo',)
...
>>> d = Demo()
>>> d.foo = 'bar'
>>> d.bar = 'foo'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Demo' object has no attribute 'bar'
And vice-versa, if you create a subclass of int
and not give your subclass a __slots__
variable, you can add arbitrary attributes to that subclass:
>>> class MyInt(int):
... pass
...
>>> mi = MyInt(6)
>>> mi.foo = 'bar'
Upvotes: 10