Why date do not construct from date?

Gabriel Genellina gagsl-py2 at yahoo.com.ar
Wed Jun 3 07:44:34 CEST 2009

En Tue, 02 Jun 2009 08:07:32 -0300, Lie Ryan <lie.1296 at gmail.com> escribió:
> Gabriel Genellina wrote:
>> En Tue, 02 Jun 2009 03:14:22 -0300, Chris Rebert <clp2 at rebertia.com>
>> escribió:
>>> On Mon, Jun 1, 2009 at 10:25 PM, Alexandr N Zamaraev
>>> <tonal at promsoft.ru> wrote:
>>>>>>> import datetime as dt
>>>>>>> d = dt.date(2009, 10, 15)
>>>>>>> dt.date(d)
>>>> Traceback (most recent call last):
>>>>  File "<stdin>", line 1, in <module>
>>>> TypeError: function takes exactly 3 arguments (1 given)
>>>> Why int form int, str from str, Decumal from Decumal can construct
>>>> bat date from date not?
>>> Probably because the function signatures would be so different. str(),
>>> int(), etc *always* take *exactly one* argument -- the object to
>>> convert. In contrast, date() takes several integers corresponding to
>>> the year, month, and day. Adding a second signature to it that took
>>> exactly one argument (of type `date`) and copied it would be
>>> significantly different from its other signature; in idiomatic Python,
>>> one would typically make a separate, new function for this drastically
>>> different signature.
>> That doesn't convince me. It's not very consistent along the various
>> types: int("3ab0",16) is rather different than int(3.2) but they're the
>> same function...
> Strictly speaking int("3ab0",16) does not create an int from an int,
> instead it creates an int from a string.
> Maybe you want to say int(3) -> 3 ?

I was replying to the argument "different signature => separate function".

>>> However, the `date` type is immutable, so there's no reason at all to
>>> try and copy a new instance from an existing one anyway, thus a
>>> single-argument copy-constructor is completely unnecessary, hence why
>>> there isn't one.
>> Isn't the same for all other examples (int, float, str, Decimal...)?
>> They're all immutable types, and some have several and rather different
>> constructor signatures:
> int(ob), float(ob), and str(ob) are type casting (strictly speaking it
> is not a type casting, but you get the idea); while date() is a
> constructor for the date object. Strictly speaking int(ob), float(ob),
> and str(ob) merely calls the special ob.__int__, ob.__float__, and
> ob.__str__.

Well, not really:

py> "10".__int__
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__int__'
py> "10".__float__
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__float__'

int() and float() do the work themselves when given a string (they look
more like "true" constructors than str(), which delegates to __str__ as
you already said)

En Tue, 02 Jun 2009 08:23:27 -0300, Lie Ryan <lie.1296 at gmail.com> escribió:

> In fact, the doc of int and float says "Convert a string or number to an
> integer, if possible" and "Convert a string or number to a floating
> point number, if possible" respectively. There is no mention that they
> are constructors at all...

I think this comes from the prehistoric ages when int/float/str were  
functions, not built-in types.

En Tue, 02 Jun 2009 04:45:19 -0300, Peter Otten <__peter__ at web.de>  

> For date you'd have to make the type check anyway, e. g.
> if isinstance(x, tuple):
>    x = date(*x)
> else:
>    x = date(x) # useless will only succeed if x already is a date
> as there would be no other way to create a date from a single value.
> So the date() call in the else branch is completely redundant unless you
> change date() to accept multiple types via the same signature:
> for x in "2000-01-01", datetime.now(), (2000, 1, 1):
>     print date(x)

That's a more pragmatic response, in the line "because it isn't very  
useful". I can accept this other too: "because whoever wrote the datetime  
module didn't care to provide such constructor".

Gabriel Genellina

More information about the Python-list mailing list