AttributeError при использовании импорта dateutil и dateutil.parser.parse(), но нет проблем при использовании синтаксического анализатора импорта из dateutil

Я играл с модулем dateutil в Python 2.7.3. Я просто хотел использовать:

import dateutil
dateutil.parser.parse("01-02-2013")

Но я получил ошибку:

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

Я проверил, какие атрибуты у dateutil есть:

print dir(dateutil)
# output: ['__author__', '__builtins__', '__doc__', '__file__', '__license__',
#          '__name__', '__package__', '__path__', '__version__']

Дело в том, что когда я пытаюсь напрямую импортировать parser из dateutil, кажется, что он существует:

from dateutil import parser
print parser.parse("01-02-2013")
# output: 2013-01-02 00:00:00

После from dateutil import parser в самом импортированном dateutil волшебным образом появилось parser:

print dir(dateutil)
# output: ['__author__', '__builtins__', '__doc__', '__file__', '__license__',
#          '__name__', '__package__', '__path__', '__version__', 'parser',
#          'relativedelta', 'tz']

Обратите внимание, что некоторые другие атрибуты (например, rrule) по-прежнему отсутствуют в этом списке.

Кто-нибудь знает, что происходит?


person Stefan van den Akker    schedule 30.04.2014    source источник


Ответы (1)


Вы не импортировали dateutil.parser. Вы можете его увидеть, но вам нужно каким-то образом его импортировать.

>>> import dateutil.parser
>>> dateutil.parser.parse("01-02-2013")
datetime.datetime(2013, 1, 2, 0, 0)

Это потому, что parser.py является модулем в пакете dateutil. Это отдельный файл в структуре папок.

Ответьте на вопрос, который вы задали в комментариях, причина, по которой relativedelta и tz появляются в пространстве имен после того, как вы from dateutil import parser, заключается в том, что parser сама импортирует relativedelta и tz.

Если вы посмотрите на исходный код dateutil/parser.py, вы увидите импорт.

# -*- coding:iso-8859-1 -*-
"""
Copyright (c) 2003-2007  Gustavo Niemeyer <[email protected]>

This module offers extensions to the standard Python
datetime module.
"""
... snip ...
from . import relativedelta
from . import tz
person msvalkon    schedule 30.04.2014
comment
Я думал, что вы можете просто импортировать его, как любой другой модуль. Например, если бы я хотел использовать datetime.date.today(), я бы сначала import datetime, а затем print datetime.date.today(). Есть ли причина, по которой это не сработает для dateutil? - person Stefan van den Akker; 30.04.2014
comment
Я понимаю. Итак, все остальные атрибуты в dateutil (например, rrule) являются отдельными файлами, и поэтому вам всегда нужно использовать import dateutil.[attribute_name] для их использования? - person Stefan van den Akker; 30.04.2014
comment
Другое дело, что date — это класс в файле datetime.py, тогда как dateutil.parser — это фактически отдельный файл, а parser.py — в пакете dateutil. - person msvalkon; 30.04.2014
comment
@Нефтас, да, это почти все. - person msvalkon; 30.04.2014
comment
Спасибо! Любые мысли о том, почему после from dateutil import parser второй print dir(dateutil) вдруг показывает relativedelta и tz? - person Stefan van den Akker; 30.04.2014
comment
Вот и все, отредактировал мой ответ, включив в него ответ на вопрос о пространстве имен. - person msvalkon; 30.04.2014