2017-10-08 26 views
0

我想定义我自己的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是否可扩展?

回答

1

str.format本身不可扩展。然而,有两种方式:


1.

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

覆盖的format_field(obj, format_spec)方法赶上调用format_spec。然后直接调用你的格式化程序。

这段代码可以帮助你(它的工作原理与PY 3.5 & 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,而不是自定义对象,所以这种方法也没有多大帮助。


随着结论:

是,你在这个问题的解决方案是充分的,可能是最简单的一种。

+1

使用python 3,你可以使用'f-string'来调用字符串中的函数。所以'f'方法{fn('a')}''变成''方法* a *“' – GiantsLoveDeathMetal

1

在python 3中,你可以调用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*' 
+0

我使用Python 2,如标签所示。 – sds

相关问题