Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I have a script that needs to execute the following at different lines in the script:

today_date = datetime.date.today()
date_time = datetime.strp(date_time_string, '%Y-%m-%d %H:%M')

In my import statements I have the following:

from datetime import datetime
import datetime

I get the following error:

AttributeError: 'module' object has no attribute 'strp'

If I change the order of the import statements to:

import datetime
from datetime import datetime

I get the following error:

AttributeError: 'method_descriptor' object has no attribute 'today'

If I again change the import statement to:

import datetime

I get the following error:

AttributeError: 'module' object has no attribute 'strp'

What is going on here and how do I get both to work?

There is no strp method on datetime.datetime either, you probably meant datetime.datetime.strptime() instead. – Martijn Pieters Mar 29, 2013 at 16:45

Your trouble is that you have some code that is expecting datetime to be a reference to the datetime module and other code that is expecting datetime to be a reference to the datetime class. Obviously, it can't be both.

When you do:

from datetime import datetime
import datetime

You are first setting datetime to be a reference to the class, then immediately setting it to be a reference to the module. When you do it the other way around, it instead ends up being a reference to the class. Last assignment "wins."

You need to rename one of these references. For example:

import datetime as dt
from datetime import datetime

Then you can change references in the form datetime.xxxx that refer to the module to dt.xxxx.

Or else just import datetime and change all references to use the module name. In other words, if something just says datetime(...) you need to change that reference to datetime.datetime.

Python has a fair bit of this kind of thing in its library, unfortunately. If they followed their own naming guidelines in PEP 8, the datetime class would be named Datetime and there'd be no problem using both datetime to mean the module and Datetime to mean the class.

renaming the module doesn't seem like a good option. Either use import datetime or from datetime import datetime, not both. – jfs Feb 28, 2015 at 10:17 I think the best is to just do import datetime, and then when using the class, do datetime.datetime. This way the code is clear and less prone to errors. It's annoying to carry datetime.datetime throughout all the code but the poor naming of this library leaves no option for the sake of clarity IMO. – Dnaiel May 24, 2017 at 12:23 Per @kindall suggestion of PEP 8, then I propose the following from datetime import datetime as DateTime, timedelta as TimeDelta, date as Date – Phil Huhn Nov 11, 2018 at 14:19 @jfs, why is renaming a bad option, given widespread renaming of other modules: import pandas as pd, import numpy as np etc – alancalvitti Jul 24, 2019 at 13:47 @jfs, what is wrong? I'm arguing the same thing - maybe I made it too terse to follow. The analogy is: def f()... is to import datetime as dt. Then elsewhere reference to f and dt only, not the body of the function and not datetime (module). In both cases, there are typically multiple references and both cases add context. – alancalvitti Jul 24, 2019 at 18:47

You cannot use both statements; the datetime module contains a datetime type. The local name datetime in your own module can only refer to one or the other.

Use only import datetime, then make sure that you always use datetime.datetime to refer to the contained type:

import datetime
today_date = datetime.date.today()
date_time = datetime.datetime.strptime(date_time_string, '%Y-%m-%d %H:%M')

Now datetime is the module, and you refer to the contained types via that.

Alternatively, import all types you need from the module:

from datetime import date, datetime
today_date = date.today()
date_time = datetime.strptime(date_time_string, '%Y-%m-%d %H:%M')

Here datetime is the type from the module. date is another type, from the same module.

Thank you very much Martijn. It is confusing why they named a type with the same name as the module. I'm a newbie with python and developing in general so maybe this is some sort of best practice. In any case thank you kindly. – codingknob Mar 29, 2013 at 17:09 @codingknob it's not, they messed up with this. The official python style guide (PEP8) explicitly says to name things differently, but I guess this code is from before the publication of the style guide.. – Fabiano Dec 4, 2019 at 23:51 @Fabiano the style guide also has things to say about flexibility and consistency within a codebase. The types were lowercased because other Python standard types are lowercased. list, dict, set, str, int, float, tuple, bool, so datetime, date, timedelta naturally follow. – Martijn Pieters Dec 5, 2019 at 8:26 @Fabiano the thing is: datetime was developed by Tim Peters who saw it as part of the core builtins in the early 2000s (while he and I both worked at Zope Corp). PEP 8 was already published and established, almost 18 months old by then. I know Tim’s reasoning because I remember some of the discussions. – Martijn Pieters Dec 8, 2019 at 0:38 @Fabiano: Decimal on the other hand started earlier, as an external project named FixedPoint, also by Tim. The difference being that it was an external project to start with. – Martijn Pieters Dec 8, 2019 at 0:43

datetime is a module which contains a type that is also called datetime. You appear to want to use both, but you're trying to use the same name to refer to both. The type and the module are two different things and you can't refer to both of them with the name datetime in your program.

If you need to use anything from the module besides the datetime type (as you apparently do), then you need to import the module with import datetime. You can then refer to the "date" type as datetime.date and the datetime type as datetime.datetime.

You could also do this:

from datetime import datetime, date
today_date = date.today()
date_time = datetime.strp(date_time_string, '%Y-%m-%d %H:%M')

Here you import only the names you need (the datetime and date types) and import them directly so you don't need to refer to the module itself at all.

Ultimately you have to decide what names from the module you need to use, and how best to use them. If you are only using one or two things from the module (e.g., just the date and datetime types), it may be okay to import those names directly. If you're using many things, it's probably better to import the module and access the things inside it using dot syntax, to avoid cluttering your global namespace with date-specific names.

Note also that, if you do import the module name itself, you can shorten the name to ease typing:

import datetime as dt
today_date = dt.date.today()
date_time = dt.datetime.strp(date_time_string, '%Y-%m-%d %H:%M')
                But also bearing in mind, that if you don't use the actual module, then using import datetime as dt does not shorten your typing as much as from datetime import datetime, because then instead of having to type dt.datetime everywhere, you can just type datetime, and also no-one is reading your code wondering "what the heck is 'dt'?".
– NeilG
                Nov 10, 2020 at 22:53

The difference between from datetime import datetime and normal import datetime is that , you are dealing with a module at one time and a class at other.

The strptime function only exists in the datetime class so you have to import the class with the module otherwise you have to specify datetime twice when calling this function.

The thing here is that , the class name and the module name has been given the same name so it creates a bit of confusuion.

today_date = datetime.date.today() date_time = dt.strptime(date_time_string, '%Y-%m-%d %H:%M')

strp() doesn't exist. I think you mean strptime.

today=datetime.today() print("Todays Date:",today) yesterday=today-datetime,timedelta(days=1) print("Yesterday date:",yesterday) tommorrow=today+datetime.timedelta(days=1) print("Tommorrow Date:",tommorrow) Code-only answers are discouraged. Please click on edit and add some words summarising how your code addresses the question, or perhaps explain how your answer differs from the previous answer/answers. From Review – Nick Jan 29, 2019 at 2:09

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.