Python: pytz возвращает непригодный __repr __ () - PullRequest
3 голосов
/ 01 октября 2010

Я понимаю, что цель repr() - вернуть строку, которую можно использовать для оценки как команды python, и вернуть тот же объект.К сожалению, pytz, похоже, не очень дружит с этой функцией, хотя это должно быть довольно легко, поскольку pytz экземпляры создаются с помощью одного вызова:

import datetime, pytz
now = datetime.datetime.now(pytz.timezone('Europe/Berlin'))
repr(now)

возвращает:

datetime.datetime(2010, 10, 1, 13, 2, 17, 659333, tzinfo=<DstTzInfo 'Europe/Berlin' CEST+2:00:00 DST>)

, который нельзя просто скопировать в другое окно ipython и оценить, потому что он возвращает синтаксическую ошибку для атрибута tzinfo.

Есть ли какой-либо простой способ дать ему напечатать:

datetime.datetime(2010, 10, 1, 13, 2, 17, 659333, tzinfo=pytz.timezone('Europe/Berlin'))

, когда строка 'Europe/Berlin' уже отчетливо видна в исходном выводе repr()?

1 Ответ

1 голос
/ 01 октября 2010
import datetime
import pytz
import pytz.tzinfo

def tzinfo_repr(self):
    return 'pytz.timezone({z})'.format(z=self.zone)
pytz.tzinfo.DstTzInfo.__repr__=tzinfo_repr

berlin=pytz.timezone('Europe/Berlin')
now = datetime.datetime.now(berlin)
print(repr(now))
# datetime.datetime(2010, 10, 1, 14, 39, 4, 456039, tzinfo=pytz.timezone("Europe/Berlin"))

Обратите внимание, что pytz.timezone("Europe/Berlin") летом может означать нечто иное, чем pytz.timezone("Europe/Berlin")) зимой, из-за перехода на летнее время. Таким образом, исправленная обезьяна __repr__ не является правильным представлением self за все время. Но он должен работать (за исключением крайних угловых случаев) в течение времени, которое требуется для копирования и вставки в IPython.


Альтернативным подходом будет подкласс datetime.tzinfo:

class MyTimezone(datetime.tzinfo):
    def __init__(self,zone):
        self.timezone=pytz.timezone(zone)
    def __repr__(self):
        return 'MyTimezone("{z}")'.format(z=self.timezone.zone)
    def utcoffset(self, dt):
        return self.timezone._utcoffset
    def tzname(self, dt):
        return self.timezone._tzname
    def dst(self, dt):
        return self.timezone._dst

berlin=MyTimezone('Europe/Berlin')
now = datetime.datetime.now(berlin)
print(repr(now))
# datetime.datetime(2010, 10, 1, 19, 2, 58, 702758, tzinfo=MyTimezone("Europe/Berlin"))
...