2017-10-08 24 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

相關問題