[Tutor] could somebody please explain...

Danny Yoo dyoo at hashcollision.org
Wed Oct 1 19:21:49 CEST 2014


> !> Also, I found something that I can’t get my mind around. It is part of
> !> the time/date protocols. I’ve not seen it anywhere else.
> !>
> !> Datetime(year=blah, blah, blah).date/time()
> !>
> !> datetime(2013,3,6).date() #returns…
> !> datetime.date(2013,3,6)
> !>
> !> datetime(2013,3,6).time() #returns…
> !> datetime.time(0,0)
> !>
> !> This is one of the weirder things I’ve run across. Is this
> !> allowed/needed in other functions/classes, or is it a datetime thing
> !only?
> !
> !
> !Can you say more about what you expect?  It may help to be very
> !explicit, even if it seems silly.  The problem with talking with
> !experienced tutors and programmers is that our perspective has warped
> !slightly from extended exposure.  :P  So we may need a bit of hinting to
> !tell what you're referring to by weirdness.
> !
>
> Sure, the interest is regarding the '2013,3,6' in the first datetime. I've not seen something in the first set of parenthesis before. Is the first one a class or a function, how can you tell without looking at its internals or some documentation?


Hi Clayton,


I will assume that, at the very beginning of your program, you've done:

   from datetime import datetime

or something equivalent to this.


The expression:

    datetime(2013,3,6).date()

can be rewritten as two separate pieces:

    t = datetime(2013, 3, 6)
    t.date()

with the difference that, in the original expression, the result of
the `datetime(2013,3,6)` is not given an explicit variable name, but
is directly used as part of a larger expression.

You will have seen this before.  For example, in the function:

#############################################
def c2f(c):
    """Returns conversion from celsius to fahrenheit."""
    return (c * 9/5) + 32
#############################################

the mathematical expression:

    (c * 9/5) + 32

has two parts to it.

We could have rewritten the c2f() function as this:

#############################################
def c2f(c):
    """Returns conversion from celsius to fahrenheit."""
    t = c * 9/5
    f = t + 32
    return f
#############################################

where we store the value of each expression with a variable name.
Similar meaning, but more verbose.  Sometimes we don't need to name
every value because otherwise the code is pedantic.  But sometimes
names help make large expressions easier to understand.  Good taste is
the judge.


One of the key things about expressions is that they "compose": they
act like lego in the sense that you can plug them into each other with
very few restrictions.  So this expression composition is what's
happening in:

    datetime(2013,3,6).date()

[More technical note: grammatically, the expression above is an
"attribute reference", as defined in:
https://docs.python.org/2/reference/expressions.html#attribute-references.
The left hand side of an attribute reference expression can itself be
a "primary" sub-expression as defined by the grammar.]



As for the return value of datetime(2013,3,6):  whether it returns an
object or something else, you have to trust the documentation.  In
Python, object construction uses the same syntax as a function call.
This is different than from a few other languages, where object
construction has a distinct syntax.  One of the advantages of having a
uniform syntax is that it's easier to later swap out the object
construction with something more sophisticated, such as: memoization,
or pooling, or other managed work.  The disadvantage is that it's
harder to see from the source code alone where allocations occur.

The documentation of:

    https://docs.python.org/2/library/datetime.html#datetime.datetime

tells us that the return value of:

    datetime(2013,3,6)

is an instance of the datetime class in the datetime module.  (It's a
bit unfortunate that the class name and the module name use the same
name, so as to encourage confusion.)


More information about the Tutor mailing list