写程序时,有时候需要根据变量生成一个新的字符串,比如将数据处理后得到的结果写入一定规则的不同文件filename_seed.txt(seed随机数,100,200, …),再比如根据变量生成完整的sql语句,再者就是写入文件或print的字符串格式化。本文介绍多种格式化字符串方法,包括str.format,format % 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 ::= +
conversion ::= "r" | "s"
format_spec ::=
>>> "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 ::= [[fill]align][sign][#][0][width][,][.precision][type]
fill ::=
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
>>> print '%(language)s has %(number)03d quote types.' % {"language": "Python", "number": 2}
Python has 002 quote types.
3. 模板字符串
from string import Template
s = Template('$who likes $what')
>>> s1 = s.substitute(who='tim', what='kung pao')
>>> print(s1)
tim likes kung pao