Python使用笔记:格式化字符串

写程序时,有时候需要根据变量生成一个新的字符串,比如将数据处理后得到的结果写入一定规则的不同文件filename_seed.txt(seed随机数,100,200, …),再比如根据变量生成完整的sql语句,再者就是写入文件或print的字符串格式化。本文介绍多种格式化字符串方法,包括str.formatformat % values

1. 连接字符串

连接字符串,最简单的就是用加号。但对于可iterable的数据,用str.join(iterable)明显优雅得多。str.join将iterable中的元素用str连起来,这用于格式化输出还是很好用。比如将sql查询的结果格式化输出,源代码如下:

with open(filename, 'w') as fp : # fp is a file object
            for row in self.cur.fetchall() :
                s = '\t'.join(str(item) for item in row)
                fp.write(s + '\n')

2. 字符串含有变量

2.1 str.format

字符串中的变量用大括号{}括起来,在format()将参数传进去。比如写一个函数根据某些变量查询数据库,并返回结果。用参数替换sql字符串中的变量形成完整的sql语句。举例如下:

def getDATimeStation(self, parent_station):
    serviceType = "calendar.monday=1 AND calendar.tuesday=1 AND calendar.wednesday=1 AND calendar.thursday=1 AND calendar.friday=1"

    sql='''
    SELECT DISTINCT stops.stop_name, routes.route_short_name, 'D' AS 'D/A', stop_times.departure_time AS 'time'
    FROM stops
    JOIN stop_times ON stops.stop_id=stop_times.stop_id AND stop_times.stop_sequence='0' AND stops.parent_station="{parent_station}"
    JOIN trips ON stop_times.trip_id=trips.trip_id 
    JOIN routes ON routes.route_id=trips.route_id
    JOIN calendar ON trips.service_id=calendar.service_id AND {serviceType}
    '''.format(parent_station=parent_station, serviceType=serviceType)
    
    cur = self.db.cursor()
    cur.execute(sql)  
    data = cur.fetchall()   
    cur.close()
    
    return datadata

值得注意的是,如果参数是只包含数字的字符串,需要在字符串变量两侧加引号(或者利用!r标志),否则被视为数字处理,在执行sql语句时会提示“Truncated incorrect DOUBLE value”警告,虽说是警告,但也查询不到正确结果。举例如下:

sid = "34"  -- type(sid) is string, like 34, 34s

-- 错误做法
sql = '''SELECT * FROM table_name WHERE sid={sid}'''.format(sid=sid)
SELECT * FROM table_name WHERE sid=34   -- 字符串"34"变成数值34
 
-- 正确做法
sql = 'SELECT * FROM table_name WHERE sid=\"{sid}\"'.format(sid=sid)
-- 或者是
sql = 'SELECT * FROM table_name WHERE sid={sid!r}'.format(sid=sid)

'SELECT * FROM table_name WHERE sid="34"'

str.format使用方法如下:

str.format(*args, **kwargs)

replacement_field ::=  "{" [field_name] ["!" conversion] [":" format_spec] "}"

field_name        ::=  arg_name ("." attribute_name | "[" element_index "]")*
arg_name          ::=  [identifier | integer]
attribute_name    ::=  identifier
element_index     ::=  integer | index_string
index_string      ::=  <any source character except "]"> +

conversion        ::=  "r" | "s"

format_spec       ::=  <described in the next section>

详情见Format String Syntax,摘抄两个例子如下:

>>> "The sum of 1 + 2 is {0}".format(1+2)
'The sum of 1 + 2 is 3'

>>> c = 3-5j
>>> ('{0} is formed from the real part {0.real} and the imaginary part {0.imag}.').format(c)
'(3-5j) is formed from the real part 3.0 and the imaginary part -5.0.'

format_spec如下,详情见Format Specification Mini-Language

format_spec ::=  [[fill]align][sign][#][0][width][,][.precision][type]
fill        ::=  <any character>
align       ::=  "<" | ">" | "=" | "^"
sign        ::=  "+" | "-" | " "
width       ::=  integer
precision   ::=  integer
type        ::=  "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"

2.2 format % values

看下面这个例子,其他参考官方文档《String Formatting Operations》。

>>> print '%(language)s has %(number)03d quote types.' % {"language": "Python", "number": 2}
Python has 002 quote types.

3. 模板字符串

官方文档Template strings,举例如下:

from string import Template
s = Template('$who likes $what')

>>> s1 = s.substitute(who='tim', what='kung pao')
>>> print(s1)
tim likes kung pao

发表评论

电子邮件地址不会被公开。 必填项已用*标注