使用惰性字典的str.format()函数?

3

我想使用str.format(),并传递一个自定义的懒加载字典。

str.format()应该只访问它需要的懒加载字典中的键。

这是可能的吗?

懒加载字典需要实现哪个接口?

更新

这不是我想要的:

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

我需要类似这样的东西:
'{a}'.format(**d)

需要在Python2.7上运行


1
str.format() 应该只访问它需要的懒字典中的键” 。它已经做到了这一点。它没有迭代整个字典! - Bakuriu
1
@Bakuriu 但是在 **d 的情况下,转换会访问所有项。 - glglgl
3个回答

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())

你可以将这些元素放入字典中,例如:

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

我没有测试过这个,但我认为它可以满足你的需求。
在最后一次编辑之后,它现在也可以使用!r!s

0

您可以使用__format__方法(仅适用于Python 3)。请参见此处的文档。


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'

谢谢您的回答。我已经更新了我的问题。非常抱歉,我没有更详细地解释我的想法。请再次查看问题。 - guettli
@guettli 嗯,现在我不知道如何回答你的问题了;实际上,看起来我甚至无法引起你问题的兴趣 :-/ - Joël

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