str.format()与懒惰的字典?

时间:2014-01-14 11:27:26

标签: python python-2.7 formatting lazy-loading

我想使用str.format()并将其传递给自定义懒惰词典。

str.format()应该只访问所需的懒字中的密钥。

这可能吗?

lazy_dict需要实现哪个接口?

更新

这不是我想要的:

'{0[a]}'.format(d)

我需要这样的东西:

'{a}'.format(**d)

需要在Python2.7上运行

3 个答案:

答案 0 :(得分:1)

对于'{a}'.format(**d),尤其是**d部分,“懒惰”字典会转换为常规字典。以下是所有键的访问权限,format()无法对其执行任何操作。

您可以制作一些替代元素的代理对象,并在字符串访问时执行“真正的”工作。

这样的东西
class LazyProxy(object):
    def __init__(self, prx):
        self.prx = prx
    def __format__(self, fmtspec):
        return format(self.prx(), fmtspec)
    def __repr__(self):
        return repr(self.prx())
    def __str__(self):
        return str(self.prx())

您可以将这些元素放入dict中,例如

interd = { k, LazyProxy(lambda: lazydict[k]) for i in lazydict.iterkeys()}

我没有对此进行测试,但我认为这可以满足您的需求。

在上次修改后,它现在也适用于!r!s

答案 1 :(得分:0)

您可以使用__format__方法(仅限Python 3)。请参阅文档here

答案 2 :(得分:0)

如果我正确理解您的问题,您希望传递一个自定义词典,该词典仅在需要时计算值。首先,我们正在寻找__getitem__()

的实施
>>> class LazyDict(object):
...    def __init__(self, d):
...        self.d = d
...    def __getitem__(self, k):
...        print k             # <-- tracks the needed keys
...        return self.d[k]
...
>>> d = D({'a': 19, 'b': 20})
>>> '{0[a]}'.format(d)
a
'19'

这表明只访问了密钥'a'; 'b'不是,所以你已经拥有了懒惰访问权限。

但是,任何对象属性都可以str.format这种方式使用,并且使用@property装饰器,您可以访问函数结果:

class MyObject(object):
    def __init__(self):
        self.a = 19
        self.b = 20
    def __getitem__(self, var): 
        return getattr(self, var)
        # this command lets you able to call any attribute of your instance,
        # or even the result of a function if it is decorated by @property:
    @property
    def c(self):
        return 21

使用示例:

>>> m = MyObject()
>>> '{0[c]}'.format(m)
'21'

但请注意,这也有效,使格式化字符串有点具体,但不需要__getitem__()实现。

>>> '{0.c}'.format(m)
'21'