python中的formatter的详细用法
今天抽空学习了一下python中的string service中的formatter的相关用法,主要是为了让自己的代码看起来更加和谐,因为很多java或者c语言过来的开发者都不怎么爱使用python的原生的字符串格式化工具,似乎大家都爱用下面的格式化工具
info = 'my name is %s I really enjoy %s' % ('younger', 'python')
现在我要学习使用更加python化的字符串格式化风格。
python的buildin字符串服务模块 [string](file:///Users/youngershen-mac-book-pro/Downloads/python-2.7.8-docs-html/library/string.html) 本身提供了一些字符串操作的工具类方法,其中包括一些经常会使用到的常量,和比较复杂的Formatter类,Template类,这里我要重点学习的就是string.Formatter类
[string.Formatter](file:///Users/youngershen-mac-book-pro/Downloads/python-2.7.8-docs-html/library/string.html#string-formatting)类中的方法:
format(format_string, *args, **kwargs)
format方法是string.Formatter类中的主要方法,它的参数是一个你需要去格式化的目标字符串,和一组需要去填充目标字符串的序列,比如字典和元组,format方法是对vformat方法的封装。
上面是我照文档的说明写的,其实Formatter.format方法和str.format并没有什么不同,他们的语法是通用的,只要学会一种就都会了,哪个更方便就用哪个
vformat(format_string, args, kwargs)
parse(format_string)
get_field(field_name, args, kwargs)
get_value(key, args, kwargs)
上面的这几个方法是互相调用的,所以一放在一起研究,其中Formatter.format 最终调用的是Formatter.vformat方法,测试程序如下
class Person(object):
name = 'default name'
def __init__(self, name = ''):
self.name = name
me = Person('younger')
data = [me]
s = "my name is {person[0].name:^30}"
formatter = String.Formatter()
formatter.format(s, data)
输出结果:
>>> formatter.format(s, person = data)
'my name is younger '
现在用Formatter.vformat方法
formatter.vformat(s, (), {'person' : data})
输出结果:
>>> formatter.format(s, person = data)
'my name is younger '
2个方法的结果是完全一样的,只是一个包装了另一个,再Formatter.vformat方法中必须有4个参数,中间的空元组和最后的空字典必须存在,因为Formatter.vformat的参数不是 (*args, **kwargs) 而是 (args, kwargs), 这是完全不一样的,没看清楚会悲剧的。
现在继续说上面4个方法的调用顺序, get_value调用了get_field, get_field调用parse, vformat调用了 get_value, 一般情况下我们只需要调用format就足够了,上面的4个方法都是给需要继承Formatter创建自己的格式化语法的时候来覆盖掉的,不过我们可以从这4个方法分析出很多东西。
我现在执行下面的程序
for i, v in enumerate(formatter.parse(s, start = 0)):
print i, v
结果会输出:
0 ('my name is ', 'person[0].name', '^30', None)
上面是返回的第1个编号为0的元组, 这4个值分别是
(literal_text, field_name, format_spec, conversion)
我们没有canversion, 所以第4项是None, 你也可以写上一个!r或者!s
这样的话字符串就变成了
s = "my name is {person[0].name!r:^30}"
前两项都很好理解,直接看字面就懂什么意思,第三项的意思是说格式化的时候的站位符,我这里用的是空,你也可以用星号,现在把s变成这样
s ="my name is {person[0].name!r:*^30}"
输出的结果是:
"my name is **********'younger'***********"
*号充当了占位符的作用
现在执行下面的程序:
for i ,v in enumerate(formatter.parse(s)):
temp = v
formatter.get_field(temp[1], (), {'person' : data})
输出结果为:
('younger', 'person')
用文档中的话来说就是 'object'和'used_key', 这个key和get_value中的key是相同的所以要调用get_value必须先调用get_field
下面继续执行代码
ret = formatter.get_value(formatter.get_field(temp[1], (), {'person':data})[1], (), {'person':data})
这个返回的 ret就是得到的对象,一个Person类型的list ,里面只有一个对象就是最初我们填充的那个,到此为止 , 所有的方法都跑了一遍,如果我们要改写自己的format语法,那就直接继承这个类,覆盖这么几个方法就行了,其余的2个方法很容易理解,可以直接看文档。
Formatter.format的语法
这里就不采用文档里的论道的方法来说明了,直接以我的理解来说好了
只有keyword类型的format string
最简单的:
"my name is {name}".format(name = 'younger')
带有多个组合条件的
"my name is {person[0].name!r:*^30}".format(person = data_list)
上面的意思是说传入的是一个list,list中有person, keyword是person[0].name, 很好理解,就是第0个对象的name属性, 这样用起来很方便, 非常好记, 从!r开始的奇怪语法是 Format Specification Mini-Language , 其中对一些数据类型,比如百分数,正负数, 复数, 大数,时间,小数点的位数,以及格式化format string的站位符等进行了定义,用法都和我写的例子一样,没有什么复杂的,这里例子已经算是比较复杂的例子了。
只有position类型的format string
"my name is {0.name}".format(person)
同时有position和keyword的formart string
"my name is {0.name}, I am living at {area[0].city}".format(person, area_list)
这里要注意的就是position的必须写再前面,不然是不能使用的,推荐大家一个格式化字符串里只用以个方式去写。
python中的formatter的详细用法的更多相关文章
- Python中的dotenv的详细用法
最简单和最常见的用法是在应用程序启动时调用load_dotenv,从当前目录或其父目录中的.env文件或指定的路径加载环境变量,然后你可以调用os.getenv提供的与环境相关的方法. .env 文件 ...
- Python中logging模块的基本用法
在 PyCon 2018 上,Mario Corchero 介绍了在开发过程中如何更方便轻松地记录日志的流程. 整个演讲的内容包括: 为什么日志记录非常重要 日志记录的流程是怎样的 怎样来进行日志记录 ...
- 【转】java.util.vector中的vector的详细用法
[转]java.util.vector中的vector的详细用法 ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.uti ...
- 简单说明Python中的装饰器的用法
简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下 装饰器对与 ...
- Python中【__all__】的用法
Python中[__all__]的用法 转:http://python-china.org/t/725 用 __all__ 暴露接口 Python 可以在模块级别暴露接口: __all__ = [&q ...
- python中enumerate()函数用法
python中enumerate()函数用法 先出一个题目:1.有一 list= [1, 2, 3, 4, 5, 6] 请打印输出:0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 打印输 ...
- Python中try...except...else的用法
Python中try...except...else的用法: try: <语句>except <name>: <语句> #如果在try ...
- (转)Python中的split()函数的用法
Python中的split()函数的用法 原文:https://www.cnblogs.com/hjhsysu/p/5700347.html Python中有split()和os.path.split ...
- Python中zip()与zip(*)的用法
目录 Python中zip()与zip(*)的用法 zip() 知识点来自leetcode最长公共前缀 Python中zip()与zip(*)的用法 可以看成是zip()为压缩,zip(*)是解压 z ...
随机推荐
- MAVEN 工程打包resources目录外的更多资源文件
首先,来看下MAVENx项目标准的目录结构: 一般情况下,我们用到的资源文件(各种xml,properites,xsd文件等)都放在src/main/resources下面,利用maven打包时,ma ...
- linux防火墙 基础知识
转 http://drops.wooyun.org/tips/1424 iptables介绍 linux的包过滤功能,即linux防火墙,它由netfilter 和 iptables 两个组件组成. ...
- SCOI2013 多项式的运算
---恢复内容开始--- 又是一道裸数据结构题. 之前受序列操作的蛋疼写法影响,只用一个tag,不知道怎么记,之后看了下别人的,终于领悟要用两个tag,一个add,一个mul,维护相当简单,想清楚就行 ...
- jquery ajaxform上传文件返回不提示信息的问题
在使用jquery的ajaxform插件进行ajax提交表单并且上传文件的时候,返回类型datatype :json但是后台通过写出一个json对象后,在执行完以后没有进入success函数,而是直接 ...
- Node.js连接数据库
Node.js连接数据库前,须要安装对应的包.假设安装sql server 须要先装包node-sqlserver. 我们以mysql为案例来说明node.js查询mysql数据. 1.安装 node ...
- Android中的Zip解压缩
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import ...
- [Flux] Component / Views
The application will dislay a some catalogs, and each catalog has title image, description. Catalog: ...
- 安全框架Shiro和Spring Security比较
Shiro 首先Shiro较之 Spring Security,Shiro在保持强大功能的同时,还在简单性和灵活性方面拥有巨大优势. Shiro是一个强大而灵活的开源安全框架,能够非常清晰的处理认证. ...
- Python爬虫:获取糗事百科笑话
为了收集笑话也是挺拼的,我就不相信你所有的都看过了.还有,请问哪位仁兄能指点之下怎么把网上抓取到的图片写到word里面,捉摸了好久都没弄出来. 糗百不需要登录,html直接解析,只要在reques ...
- jquery ajax 提交表单(file && input)
用到的插件 jquery.js jquery.form.js[http://malsup.github.io/jquery.form.js] 提交页面 <form enctype="m ...