In datetime, why is `year` a property, but `weekday()` a function?

Viewed 283

I have a question about this piece of Python 3 script:

import datetime
d = datetime.date.today()

print(d.year)
print(d.weekday())

TIO

Why is d.year without parentheses, but d.weekday() isn't? Why is one a property and the other a function?

5 Answers

Because year is required for defining datetime.date objects and is subsequently set as a property of the class:

class datetime.date(year, month, day)

All arguments are required.

While weekday needs to be calculated via a method from year, month and day.

Probably because year is a required argument when constructing a datetime.date object. No computation is required within the object to access the year value. See the implementation:

class date:
    def __new__(cls, year, month=None, day=None):
        ...

Whereas weekday needs to be computed:

def weekday(self):
    "Return day of the week, where Monday == 0 ... Sunday == 6."
    return (self.toordinal() + 6) % 7

There's no particular reason I can think of. It's a module with a documented API which says weekday() is a method not a property. One can argue whether it should have been otherwise, but as soon as the module was released and people wrote code that depended on this interface, it could no longer be changed. (Other than by deprecating the module and releasing datetime2, which the Python gods have indeed done for a few modules that were much more badly broken by design).

If it really bugs you you can 'fix' it. In Python3 (simplified super):

class MyDate( datetime.date):
    @property
    def weekday(self):
        return super().weekday()

>>> d = MyDate.today()
>>> d
MyDate(2018, 11, 14)
>>> d.weekday
2

For no good reason. It's inconsistent, and violates some basic principles. Don't read too much into it, it was probably some instant decision that stuck.

Because weekday need some operations.

Related