【问题标题】:Python: pytz returning unusable __repr__()Python:pytz 返回不可用的 __repr__()
【发布时间】:2011-04-19 19:25:56
【问题描述】:

我了解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 还是任意时区?
  • 可以是任何时区。我想要一个 datetime 对象的 pythonic 表示,我可以在 ipython shell 中复制&粘贴&执行,并获取带有其时区的原始时间戳。所以请不要将全球转换为 UTC。
  • 仅供参考:建议repr 可用于复制对象,但这不是必需的。
  • @Daenyth:如果推荐的话,如果这样的通用库的开发者可以使用它就好了。

标签: python instance representation pytz


【解决方案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")) 不同。因此,monkeypatched __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"))

【讨论】:

  • 看起来像我想要的,虽然看起来不是很优雅。
  • 子类化并不是真正可移植的(通过电子邮件快速向某人发送 datetime(...) 构造函数调用行),但它可能是 ipython 中本地使用的最简单的解决方案。谢谢!
  • 看起来很可怕,但你有没有考虑过发送腌制物品,例如import cPickle; cPickle.loads("cdatetime\ndatetime\np1\n(S'\\x07\\xda\\n\\x01\\x151+\\x0c\\x13\\xd0'\ncpytz\n_p\np2\n(S'Europe/Berlin'\np3\nI7200\nI3600\nS'CEST'\np4\ntRp5\ntRp6\n.")
  • 不,因为它看起来很糟糕,我也希望能够阅读该行。我正在考虑联系 pytz 开发人员并询问他们的 repr 是否可以更改...
  • 请注意__repr__ 应该提供足够的信息来重新生成对象。将__repr__ 设置为返回"pytz.timezone(...)" 失败,因为它忽略了夏令时问题。
猜你喜欢
  • 2021-12-06
  • 2012-11-23
  • 2018-05-06
  • 2015-01-23
  • 2020-02-07
  • 2018-06-24
  • 2016-01-18
  • 2015-08-18
  • 2014-10-06
相关资源
最近更新 更多