22

I have this code:

>>> class G:
...   def __init__(self):
...     self.x = 20
...
>>> gg = G()
>>> gg.x
20
>>> gg.y = 2000

And this code:

>>> from datetime import datetime
>>> my_obj = datetime.now()
>>> my_obj.interesting = 1
*** AttributeError: 'datetime.datetime' object has no attribute 'interesting'

From my Python knowledge, I would say that datetime overrides setattr/getattr, but I am not sure. Could you shed some light here?

EDIT: I'm not specifically interested in datetime. I was wondering about objects in general.

Cairnarvon
  • 25,981
  • 9
  • 51
  • 65
Geo
  • 93,257
  • 117
  • 344
  • 520
  • "I was wondering about objects in general." What? You show a general example of a general class which generally has attributes added. What does your edit mean? – S.Lott Mar 08 '09 at 19:13
  • 3
    It means that I was curious about all the classes, not just datetime. I posted this question because I saw that to some classes I could add attributes, while to others I couldn't. – Geo Mar 08 '09 at 20:54
  • @Geo: some classes are different -- there's no "general" rule. As your question notes -- some classes can and some classes can't. Since your question shows that there's no general rule, what are you asking? – S.Lott Mar 08 '09 at 22:30

3 Answers3

33

My guess, is that the implementation of datetime uses __slots__ for better performance.

When using __slots__, the interpreter reserves storage for just the attributes listed, nothing else. This gives better performance and uses less storage, but it also means you can't add new attributes at will.

Read more here: http://docs.python.org/reference/datamodel.html

Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
Epcylon
  • 4,674
  • 2
  • 26
  • 35
  • 10
    Datetime is actually written in C, which gives behaviour very similar to writing a python object that uses __slots__. Slots are a way of writing objects in python that are almost as efficient as the C versions, without resorting to c – Jarret Hardie Mar 08 '09 at 13:15
  • 6
    So you could see the behaviour because the object is written in c, because it uses setattr, or because of slots :-) – Jarret Hardie Mar 08 '09 at 13:16
18

It's written in C

http://svn.python.org/view/python/trunk/Modules/datetimemodule.c?view=markup

It doesn't seem to implement setattr.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
3

While the question has already been answered; if anyone is interested in a workaround, here's an example --

mydate = datetime.date(2013, 3, 26)
mydate.special = 'Some special date annotation'  # doesn't work
...
class CustomDate(datetime.date):
    pass
mydate = datetime.date(2013, 3, 26)
mydate = CustomDate(mydate.year, mydate.month, mydate.day)
mydate.special = 'Some special date annotation'  # works
s29
  • 2,027
  • 25
  • 20