Python:pytz返回无法使用的__repr__()

3

我明白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() 的原始输出中清晰可见时,应如何处理?

ه®ƒوک¯هگ¦ه§‹ç»ˆوک¯Europe/Berlin,è؟کوک¯ه°†وک¯ن»»و„ڈو—¶هŒ؛ï¼ں - aaronasterling
它可以是任何时区。我想要一个Pythonic表示datetime对象的副本,我可以复制并在ipython shell中执行,并获取其时区的原始时间戳。因此,请不要进行全局转换为UTC。 - eumiro
请注意:建议使用repr来复制对象,但这不是必需的。 - Daenyth
@Daenyth:如果建议使用,那么这样常用库的开发者使用它会很好。 - eumiro
1个回答

1
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"))

1
不行,因为它看起来很糟糕,我也想能够阅读这一行。我正在考虑联系pytz开发人员并询问他们是否可以更改他们的__repr__... - eumiro
2
请注意,__repr__ 应该提供足够的信息以重新生成对象。将 __repr__ 设置为返回 "pytz.timezone(...)" 会失败,因为它忽略了夏令时问题。 - unutbu
它是如何忽略DST问题的?是否启用DST取决于对象包含的时间...以及2010年10月是否启用了DST在tzinfo中(是的,它还包含了历史上DST的开始/结束日期。至少Olson数据库是这样的)。 - Jürgen A. Erhard
@JürgenA.Erhard:使用datetime(...,tzinfo = pytz.timezone(...))几乎从来不是使日期时间具有时区感知的正确方法。pytz希望您使用其本地化或astimezone方法。即使pytz.timezone('Europe/Berlin')知道DST转换边界,当您使用datetime(...,tzinfo = ...)时,该信息将被忽略,并且它只是使用pytz.timezone('Europe/Berlin')中的第一个时区。 - unutbu
例如,DT.datetime(2015, 5, 4, tzinfo=pytz.timezone('Europe/Berlin')) 返回 datetime.datetime(..., tzinfo=<DstTzInfo 'Europe/Berlin' LMT+0:53:00 STD>),但实际上应该返回 datetime.datetime(..., tzinfo=<DstTzInfo 'Europe/Berlin' CEST+2:00:00 DST>) - unutbu
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接