自定义字符串格式化

自定义字符串格式化

1. 问题

如何使得一个对象支持通过format内置函数来自定义格式化输出

2. 预备知识

对内置format函数的一些理解

# 我们先来看一下format函数的文档
# 在ipython下输入"format?"回车查看文档
format?

# Signature: format(value, format_spec='', /)
# Docstring:
# Return value.__format__(format_spec)

# format_spec defaults to the empty string
# Type:      builtin_function_or_method

意思就是format函数其实就是调用了value对象的__format__ 方法
format_spec参数的意思是"格式化的规格(选项)"
所以想要自定义format的格式输出,我们只需要自定义类的__format__方法即可

3. 解决方案

为了自定义字符串的格式化,我们需要自定义类的__format__方法

class Date(object):
    
    _formats = dict(ymd='{0.year}年{0.month}月{0.day}日',
                   ymd1='{0.year}/{0.month}/{0.day}',
                   mdy='{0.month}/{0.day}/{0.year}')
    
    def __init__(self,year,month,day):
        self.year, self.month, self.day = year, month, day
    
    def __format__(self,format_spec):
        # format_spec默认为'ymd'
        format_spec = format_spec or 'ymd'
        
        # 检查format_spec如果不在self._formats中,抛出异常
        if format_spec not in self._formats:
            raise Exception(f'没有对应的format_spec,可用的参数有: {", ".join(self._formats.keys())}')
        
        return self._formats[format_spec].format(self)

d = Date(2019,9,3)

format(d) # 在类中,我们设置了format_spec默认值为ymd,输出:'2019年9月3日'

format(d,'ymd1') # '2019/9/3'

'今天是{:ymd}'.format(d) # '今天是2019年9月3日'

4. 讨论

类的__format__方法给python的字符串格式化功能提供了一个钩子,所以其实格式化代码的解析工作完全是由类自己来决定的

你可能感兴趣的:(Python杂谈)