3

Can someone explain to me the dot notation in this code?

now = datetime.now()

I know that now() refers to the method which belongs to the class datetime. Please take a look at the datetime.py module if needed.

what I'm confused about is the "datetime" part of now = datetime.now(). I read somewhere that it's supposed to be the instance of a class (the class is also called datetime if you look over the module) which the now() method belongs to, no? Since it's the instance shouldn't there be a line for the code which is

datetime = datetime()

This is to specify that the datetime instance is part of the datetime class right?

I'm sorry if this question makes no sense at all, since it's only been a day since I've been working with Python. Thank you for your time.

Zizouz212
  • 4,908
  • 5
  • 42
  • 66
  • `datetime.now()` is a static method, to use static methods it is not necessary to create an instance of the class. – eyllanesc Jul 16 '17 at 05:05

2 Answers2

3

You've run into what is called a class method.

There's a few ways of figuring this out by looking at the code:

First off, is datetime.datetime.now() really an instance? if you were to type datetime.datetime in an interpreter, this is what you would get:

>>> datetime.datetime
<type 'datetime.datetime'>

Datetime is a class. To instantiate it, you'd want to call it:

>>> datetime.datetime(2017, 7, 16, 1, 1, 47)
datetime.datetime(2017, 7, 16, 1, 1, 47)

The () brackets with arguments create an instance of the class. But when we call this now() method, there aren't any brackets!

>>> datetime.datetime.now()
datetime.datetime(2017, 7, 16, 1, 3, 30, 501644)

That's because now() is a class method. In other words, we don't require an instance of the class to call it.

If you're familiar with class instances and class definitions, you may have written this before:

class Hello(object):
    def say_message(self, message):
        print(message)

See that handy little self argument that comes first in that method? self refers to the instance of the class that is passed down. That's called an instance method. A class method doesn't give us an instance, but rather the class definition. So it doesn't require an instance.

Class methods are much more useful when you're doing advanced things with inheritance and shortcut initializations.


Class methods are usually defined with a decorator:

@classmethod
def now(cls):
    ...

This is actually the same as writing this:

def now(cls):
    ...

now = classmethod(now)

Decorators were introduced as part of PEP 318 and brought into the language in Python 2.4. Before decorators were introduced, the second method above was always used. That's because decorators are functions. The @ syntax is just to make this "decoration" more readable and clear. I would read the PEP, since it has a whole bunch of good information on how and why decorators were introduced to the language. In the datetime.now case, you can see that the second method was used to transform the method into a class method (they do this with all the class methods, including other methods like fromtimestamp:

def now(cls, tz=None):
    "Construct a datetime from time.time() and optional time zone info."
    t = _time.time()
    return cls.fromtimestamp(t, tz)
now = classmethod(now)
Zizouz212
  • 4,908
  • 5
  • 42
  • 66
  • Thank you so much for answering everyone. This is indeed a class method. I just looked at the datetime.py and found that the method now has a (cls) argument in it, which indicates it's a class method even though this "cls" argument could potentially be anything. However, i couldn't find the @classmethod decorator on top of the method. Can someone explain this? Thanks in advance –  Jul 17 '17 at 19:35
  • @user8314097 I just updated my answer. Feel free to read the update :) – Zizouz212 Jul 17 '17 at 19:51
0

I'm assuming that you imported datetime using from datetime import datetime, in that case you really did import the datetime class.

However, you don't have to first create an instance of that class if you want t use some of it's methods. Specifically the use of datetime.now() is quite common and is the right use.

In this case, the dot notation is directing python do use the method now of the class datetime and there's no contradiction in that.

Ofer Sadan
  • 11,391
  • 5
  • 38
  • 62