最近在调查配置问题过程中,发现一个比较低级的错误,应该是 python 使用习惯的问题,和大家分享一下,比较有意思。
问题介绍
在系统的配置脚本中有一句这样的逻辑:
# etcd_nodes like this: 'http://172.16.1.1:2380'
etcd_nodes.append(etcd_node_host.rstrip(':2380').lstrip('http://'))
我们预期的结果当然是获取到 '172.16.1.1' 这个 IP 地址。但是在实际使用的时候,遇到了这样的问题:
分析一下原因
我们先来看下 python 内置方法 strip 这类方法的定义了实现,官方定义:
def rstrip(self, chars=None): # real signature unknown; restored from __doc__
"""
S.rstrip([chars]) -> string or unicode
Return a copy of the string S with trailing whitespace removed.
If chars is given and not None, remove characters in chars instead.
If chars is unicode, S will be converted to unicode before stripping
"""
return ""
参数中的 chars 是字符的list,不是字符串匹配,这个字符的作用怎么理解呢?举个例子,
>>> a='test it 888888888'
>>> print a.rstrip('8')
test it
>>> a='test it8 888888888'
>>> print a.rstrip('8')
test it8
简单的说,就是匹配到最后一个不是给定 chars 的字符就停止。
那么如果传入的参数是一个字符串呢:
>>> a='test it887878888888'
>>> print a.rstrip('78')
test it
所以,这样的匹配其实就是匹配到最后一个不是 chars 这个数组中任意的一个字符为止。
这样,就能解释为什么前面的 rstrip(':2380') 对 'http://172.1.1.2:2380' 的结果是 'http://172.1.1.' 的原因
了。
结论
对于像 strip, rstrip, lstrip 这样最基本、简单的功能,还是需要了解清楚其使用方法,不能因为一次试用成功就以为满足功能需求了。这样的误用,如果上线,危害还是比较大的。