AttributeError происходит в выражении datetime - PullRequest
0 голосов
/ 27 мая 2018

Следуя инструкциям по Python, я узнал о встроенной функции repr(), которая согласно официальной документации:

Возвращает строку , содержащую печатную формупредставление объекта.Для многих типов эта функция пытается вернуть строку, которая выдаст объект с тем же значением при передаче в eval(), в противном случае представление представляет собой строку, заключенную в угловые скобки, которая вместе содержит имя типа объектас дополнительной информацией, часто включающей название и адрес объекта.Класс может управлять тем, что эта функция возвращает для своих экземпляров, определяя метод __repr__().

https://docs.python.org/3/library/functions.html#repr

Подводя итог, для многих типов объектов, включая большинство встроенных, eval(repr(obj)) == obj (или эквивалент obj == eval(repr(obj)) возвращает True , также упомянутое в вышеприведенной документации.

Но при выполнении следующего кода AttributeError: type object 'datetime.datetime' has no attribute 'datetime' встречается в последнем выражении, т.е.print(today == eval(repr(today)).

from datetime import datetime

s = 'Hello, Pythoneers'
print(s == eval(repr(s)))  # no errors here

today = datetime.now()
print(today == eval(repr(today))) # error occurs here

Может кто-нибудь объяснить причину такого поведения?

1 Ответ

0 голосов
/ 27 мая 2018

datetime использует datetime.datetime(...) в представлении:

>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2018, 5, 27, 16, 46, 59, 491342)

Это имя модуля , за которым следует имя класса, которое является атрибутом модуля:

>>> datetime
<module 'datetime' from '/.../lib/python3.6/datetime.py'>
>>> datetime.datetime
<class 'datetime.datetime'>

Имя datetime в вашем примере ссылается не на модуль, а на класс внутри модуля:

>>> from datetime import datetime  # the form used in your question
>>> datetime
<class 'datetime.datetime'>

Вместо этого используйте import datetime, затемиспользование today = datetime.datetime.now().

repr() вызывает метод object.__repr__() , который не передает никакой информации о том, как ваш код ссылается на класс;поэтому экземпляр не может отрегулировать, какую строку он генерирует.Даже если бы была доступна дополнительная информация, вы бы не захотели генерировать разные строки в любом случае ;Вы действительно хотите выяснить, что такое fluzborx.datetime(), когда кто-то в шутку где-то использовал import datetime as fluzborx?

Обратите внимание, что цель repr() состоит в помощи в отладке , а не в предоставлении полногоподдержка сериализации типов данных.Если вы хотите сериализовать datetime экземпляров, используйте правильный формат сериализации, такой как pickle, или напишите свои собственные преобразования datetime -> string and string -> datetime (например, для JSON, возможно, используйте строку ISO8601преобразования).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...