Python 字符串

来源:互联网 发布:linux 查看cpu参数 编辑:程序博客网 时间:2024/06/06 20:36
与字符串相关的问题总是很多,⽐比如池化 (intern)、编码 (encode) 等。字符串是不可变类型,保
存字符序列或⼆二进制数据。
• 短字符串存储在 arena 区域, str、unicode 单字符会被永久缓存。
• str 没有缓存机制,unicode 则保留 1024 个宽字符⻓长度⼩小于 9 的复⽤用对象。
• 内部包含 hash 值,str 另有标记⽤用来判断是否被池化。
字符串常量定义简单⾃自由,可以是单引号、双引号或三引号。但我个⼈人建议⽤用双引号表⽰示字符串,
⽤用单引号表⽰示字符,和其他语⾔言习惯保持⼀一致。
>>> "It's a book."? ? ? ? # 双引号⾥里⾯面可以⽤用单引号。
"It's a book."
>>> 'It\'s a book.'? ? ? ? # 转义
"It's a book."
>>> '{"name":"Tom"}'? ? ? # 单引号⾥里⾯面正常使⽤用双引号。
'{"name":"Tom"}'
>>> """? ? ? ? ? # 多⾏行
27
... line 1
... line 2
... """
>>> r"abc\x"?? ? ? ? # r 前缀定义⾮非转义的 raw-string。
'abc\\x'
>>> "a" "b" "c"? ? ? ? # ⾃自动合并多个相邻字符串。
'abc'
>>> "中国⼈人"? ? ? ? ? # UTF-8 字符串 (Linux 系统默认)。
'\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xba'
>>> type(s), len(s)
<type 'str'>, 9
>>> u"中国⼈人"?? ? ? ? # 使⽤用 u 前缀定义 UNICODE 字符串。
u'\u4e2d\u56fd\u4eba'
>>> type(u), len(u)
<type 'unicode'>, 3
基本操作:
>>> "a" + "b"
'ab'
>>> "a" * 3
'aaa'
>>> ",".join(["a", "b", "c"])? ? ? ? ? # 合并多个字符串。
'a,b,c'
>>> "a,b,c".split(",")? ? ? ? ? ? # 按指定字符分割。
['a', 'b', 'c']
>>> "a\nb\r\nc".splitlines()? ? ? ? ? # 按⾏行分割。
['a', 'b', 'c']
>>> "a\nb\r\nc".splitlines(True)?? ? ? ? # 分割后,保留换⾏行符。
['a\n', 'b\r\n', 'c']
>>> "abc".startswith("ab"), "abc".endswith("bc")? ? # 判断是否以特定⼦子串开始或结束。
True, True
>>> "abc".upper(), "Abc".lower()?? ? ? ? # ⼤大⼩小写转换。
'ABC', 'abc'
28
>>> "abcabc".find("bc"), "abcabc".find("bc", 2)? ? # 可指定查找起始结束位置。
1, 4
>>> " abc".lstrip(), "abc ".rstrip(), " abc ".strip()? # 剔除前后空格。
'abc', 'abc', 'abc'
>>> "abc".strip("ac")? ? ? ? ? ? # 可删除指定的前后缀字符。
'b'
>>> "abcabc".replace("bc", "BC")?? ? ? ? # 可指定替换次数。
'aBCaBC'
>>> "a\tbc".expandtabs(4)?? ? ? ? ? # 将 tab 替换成空格。
'a bc'
>>> "123".ljust(5, '0'), "456".rjust(5, '0'), "abc".center(10, '*')? # 填充
'12300', '00456', '***abc****'
>>> "123".zfill(6), "123456".zfill(4)? ? ? ? ? ? # 数字填充
'000123', '123456'
编码
Python 2.x 默认采⽤用 ASCII 编码。为了完成编码转换,必须和操作系统字符编码统⼀一起来。
>>> import sys, locale
>>> sys.getdefaultencoding()? ? # Python 默认编码。
'ascii'
>>> c = locale.getdefaultlocale(); c? # 获取当前系统编码。
('zh_CN', 'UTF-8')
>>> reload(sys)? ? ? ? # setdefaultencoding 在被初始化时被 site.py 删掉了。
<module 'sys' (built-in)>
>>> sys.setdefaultencoding(c[1])?? # 重新设置默认编码。
str、unicode 都提供了 encode 和 decode 编码转换⽅方法。
• encode: 将默认编码转换为其他编码。
• decode: 将默认或者指定编码字符串转换为 unicode。
>>> s = "中国⼈人"; s
'\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xba'
>>> u = s.decode(); u? ? ? # UTF-8 -> UNICODE
29
u'\u4e2d\u56fd\u4eba'
>>> gb = s.encode("gb2312"); gb? ? # UTF-8 -> GB2312
'\xd6\xd0\xb9\xfa\xc8\xcb'
>>> gb.encode("utf-8")? ? ? # encode 会把 gb 当做默认 UTF-8 编码,所以出错。
UnicodeDecodeError: 'utf8' codec can't decode byte 0xd6 in position 0: invalid
continuation byte
>>> gb.decode("gb2312")? ? ? # 可以将其转换成 UNICODE。
u'\u4e2d\u56fd\u4eba'
>>> gb.decode("gb2312").encode()?? # 然后再转换成 UTF-8
'\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xba'
>>> unicode(gb, "gb2312")?? ? # GB2312 -> UNICODE
u'\u4e2d\u56fd\u4eba'
>>> u.encode()? ? ? ? # UNICODE -> UTF-8
'\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xba'
>>> u.encode("gb2312")? ? ? # UNICODE -> GB2312
'\xd6\xd0\xb9\xfa\xc8\xcb'
标准库另有 codecs 模块⽤用来处理更复杂的编码转换,⽐比如⼤大⼩小端和 BOM。
>>> from codecs import BOM_UTF32_LE
>>> s = "中国⼈人"
>>> s
'\xe4\xb8\xad\xe5\x9b\xbd\xe4\xba\xba'
>>> s.encode("utf-32")
'\xff\xfe\x00\x00-N\x00\x00\xfdV\x00\x00\xbaN\x00\x00'
>>> BOM_UTF32_LE
'\xff\xfe\x00\x00'
>>> s.encode("utf-32").decode("utf-32")
u'\u4e2d\u56fd\u4eba'
格式化
Python 提供了两种字符串格式化⽅方法,除了熟悉的 C 样式外,还有更强⼤大的 format。
%[(key)][flags][width][.precision]typecode
30
标记:- 左对⻬齐,+ 数字符号,# 进制前缀,或者⽤用空格、0 填充。
>>> "%(key)s=%(value)d" % dict(key = "a", value = 10) ? # key
'a=10'
>>> "[%-10s]" % "a"? ? ? ? ? ? ? # 左对⻬齐
'[a ]'
>>> "%+d, %+d" % (-10, 10)? ? ? ? ? ? # 数字符号
'-10, +10'
>>> "%010d" % 3? ? ? ? ? ? ? # 填充
'0000000003'
>>> "%.2f" % 0.1234? ? ? ? ? ? ? # ⼩小数位
'0.12'
>>> "%#x, %#X" % (100, 200)? ? ? ? ? # ⼗十六进制、前缀、⼤大⼩小写。
'0x64, 0XC8'
>>> "%s, %r" % (m, m)? ? ? ? ? ? # s: str(); r: repr()
'test..., <__main__.M object at 0x103c4aa10>'
format ⽅方法⽀支持更多的数据类型,包括列表、字典、对象成员等。
{field!convertflag:formatspec}
格式化规范:
formatspec: [[fill]align][sign][#][0][width][.precision][typecode]
⽰示例:
>>> "{key}={value}".format(key="a", value=10)?? # 使⽤用命名参数。
'a=10'
>>> "{0},{1},{0}".format(1, 2)? ? ? ? # field 可多次使⽤用。
'1,2,1'
>>> "{0:,}".format(1234567)? ? ? ? # 千分位符号
'1,234,567'
>>> "{0:,.2f}".format(12345.6789)? ? ? # 千分位,带⼩小数位。
'12,345.68'
>>> "[{0:<10}], [{0:^10}], [{0:*>10}]".format("a")? # 左中右对⻬齐,可指定填充字符。
'[a ], [ a ], [*********a]'
>>> import sys
31
>>> "{0.platform}".format(sys)? ? ? ? # 成员
'darwin'
>>> "{0[a]}".format(dict(a=10, b=20))? ? ? # 字典
'10'
>>> "{0[5]}".format(range(10))? ? ? ? # 列表
'5'
另有 string.Template 模板可供使⽤用。该模块还定义了各种常⻅见的字符序列。
>>> from string import letters, digits, Template
>>> letters? ? ? ? ? ? ? ? ? # 字⺟母表
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> digits? ? ? ? ? ? ? ? ? # 数字表
'0123456789'
>>> Template("$name, $age").substitute(name = "User1", age = 20)? # 模板替换。
'User1, 20'
>>> Template("${name}, $age").safe_substitute(name = "User1") ? # 没找到值,不会抛出异常。
'User1, $age'
池化
在 Python 进程中,⽆无数的对象拥有⼀一堆类似 "__name__"、"__doc__" 这样的名字,池化有助于
减少对象数量和内存消耗, 提升性能。
⽤用 intern() 函数可以把运⾏行期动态⽣生成的字符串池化。
>>> s = "".join(["a", "b", "c"])
>>> s is "abc"? ? ? # 显然动态⽣生成的字符串 s 没有被池化。
False
>>> intern(s) is "abc"? ? # intern 会检查内部标记。
True
>>> intern(s) is intern(s)? ? # 以后⽤用 intern 从池中获取字符串对象,就可以复⽤用了。
True
当池化的字符串不再有引⽤用时,将被回收。
0 0
原创粉丝点击