Usually, you can set an arbitrary attribute to a custom object, for instance
----------
>>> a=A()
>>> a.foo=42
>>> a.__dict__
{'foo': 42}
>>>
----------
On the other hand, you can't do the same binding with a string object :
----------
>>> a=str("bar")
>>> a.foo=42
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'foo'
>>> a.__dict__
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__dict__'
>>>
----------
Why ?
Because the str
type is a type wich does not has an attribute dict. From the docs, "Classes" section:
A class has a namespace implemented by a dictionary object. Class attribute references are translated to lookups in this dictionary, e.g.,
C.x
is translated toC.__dict__["x"]
You can also enforce something similar on custom objects:
>>> class X(object):
... __slots__=('a', )
...
>>> a = X()
>>> a.a = 2
>>> a.foo = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'X' object has no attribute 'foo'
In general, you should not be setting nor modifying fields of objects that you are not supposed to. The documentation of the specific data type should reference you what fields are available for public modification.
For example, an ReadOnlyPoint
object, where the x and y coordinates are set only on object construction:
>>> class ReadOnlyPoint(object):
... __slots__ = ('_x', '_y')
... def __init__(self, x, y):
... self._x = x
... self._y = y
... def getx(self):
... return self._x
... def gety(self):
... return self._y
... x = property(getx)
... y = property(gety)
...
>>> p = ReadOnlyPoint(2, 3)
>>> print p.x, p.y
2 3
>>> p.x = 9
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>> p._x = 9
>>> print p.x, p.y
9 3
While the x
and y
properties are read-only, accessing the object internals allows you to alter the object's state.
The inhability to add a new field to an str
object is an implementation detail, specific to the Python version that you are using.
http://docs.python.org/reference/datamodel.html
If the class has a setattr() or delattr() method, this is called instead of updating the instance dictionary directly.
http://docs.python.org/reference/datamodel.html#object.setattr
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With