我可以定义自己的格式规范吗?

2024-04-24 11:39:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我想定义我自己的str.format()规范,例如

def earmuffs(x):
    return "*"+str(x)+"*"

使用,例如:

def triple2str(triple, fmt="g"):
    return "[{first:{fmt}} & {second:+{fmt}} | {third}]".format(
        first=triple[0], second=triple[1], third=triple[2], fmt=fmt)

以便:

## this works:
>>> triple2str((1,-2,3))
'[1 & -2 | 3]'
>>> triple2str((10000,200000,"z"),fmt=",d")
'[10,000 & +200,000 | z]'

## this does NOT work (I get `ValueError: Invalid conversion specification`)
>>> triple2str(("a","b","z"),fmt=earmuffs)
'[*a* & *b* | z]'

到目前为止我能想到的最好的办法是

def triple2str(triple, fmt=str):
    return "[{first} & {second} | {third}]".format(
        first=fmt(triple[0]), second=fmt(triple[1]), third=triple[2])

工作原理如下:

>>> triple2str((1,-2,3))
'[1 & -2 | 3]'
>>> triple2str((10000,200000,"z"),fmt="{:,d}".format)
'[10,000 & 200,000 | z]' # no `+` before `2`!
>>> triple2str((10000,200000,"z"),fmt=earmuffs)
'[*10000* & *200000* | z]'

这真的是我能做的最好的了吗? 我不高兴的是不清楚如何合并修饰符(例如,上面的+)。你知道吗

str.format可扩展吗?你知道吗


Tags: 规范formatreturn定义defthisfirsttriple
2条回答

在python3中,您可以调用f-strings中的函数,也许这会有所帮助。你知道吗

def earmuffs(val):
    return "*{}*".format(val)

form = lambda a: f"method {earmuffs(a[0])} and method {earmuffs(a[1])}"

b = ('one', 'two')

form(b)
>>>'method *one* and method *two*'

str.format本身是不可扩展的。但是,有两种方法:


1。你知道吗

使用自定义字符串格式化程序:https://docs.python.org/2/library/string.html#custom-string-formatting

重写format_field(obj, format_spec)方法以捕获可调用的格式规范,然后直接调用格式化程序。你知道吗

此代码段可以帮助您(至少适用于py 3.5和py 2.7):

import string

class MyFormatter(string.Formatter):
    def __init__(self, *args, **kwargs):
        super(MyFormatter, self).__init__(*args, **kwargs)
        self.fns = {}

    def format_field(self, value, format_spec):
        # print(repr(value), repr(format_spec))

        # intercept {fmt} part with functions:
        if callable(value):
            result = super(MyFormatter, self).format_field(value, format_spec)
            self.fns[result] = value
            return result

        # intercept {var:{fmt}} with remembered {fmt}:
        if format_spec in self.fns:
            return self.fns[format_spec](value)
        else:
            return super(MyFormatter, self).format_field(value, format_spec)


def fn(val):
    return '*{}*'.format(val)


f = MyFormatter()
print(f.format("{var:{fmt}}", var=1000, fmt='g'))
print(f.format("{var:{fmt}}", var=1000, fmt=fn))

2。你知道吗

定义每对象格式方法__format__(self, format_spec),其中format_spec是在:之后的任何内容,例如{var:g}。您可以根据需要格式化对象的自我呈现。你知道吗

但是,在您的例子中,对象是ints/strs,而不是自定义对象,因此这种方法也没有多大帮助。你知道吗


结论是:

是的,你对这个问题的解答是充分的,而且可能是最简单的。你知道吗

相关问题 更多 >