字符串处理函数大家肯定都经常用,甭管你用什么语言,这一块还是不能少的。一直以来都把python的strip理解成了去掉收尾的空格,因为用过java或者VB的程序员应该知道,有个trim可以去掉首尾的空格。不过,这次我就没那么幸运了,这回让Python给坑了一把。
1、问题描述
先上代码看一眼:
str = "30.0%"
index = int(str.strip(".0%"))/10 - 1
本来是用于计算索引值的,但是怎么调都无法调试通过。我就纳闷了,这个结果怎么就不对呢?index的值应该是多少呢?测试一下。
现在知道了,原来index的值一直是-1,
2、问题分析
去查了一下python的手册。手册是这么写的:
原来Python是按照字符去除的。你这不是坑吗?我本想去掉一个字符串,你也让我传给你个字符串,而你现在又按照字符给我去掉,这是什么意思?我去看看你家里人是怎么说的。于是,我去找了找python的源码看了一眼。
Py_LOCAL_INLINE(PyObject *)
do_strip(PyStringObject *self, int striptype)
{
char *s = PyString_AS_STRING(self);
Py_ssize_t len = PyString_GET_SIZE(self), i, j;
/*看懂下边这段就完了,上边是python的C扩展包装用的*/
i = 0;
if (striptype != RIGHTSTRIP) {
while (i < len && isspace(Py_CHARMASK(s[i]))) {
i++;
}
}
j = len;
if (striptype != LEFTSTRIP) {
do {
j--;
} while (j >= i && isspace(Py_CHARMASK(s[j])));
j++;
}
if (i == 0 && j == len && PyString_CheckExact(self)) {
Py_INCREF(self);
return (PyObject*)self;
}
else
return PyString_FromStringAndSize(s+i, j-i);
}
其实,上边代码很简单,就不解释了。我很怀疑它为什么是这么设计的呢?怀着好奇,我去找了一下java的源代码,找到了下边这段:
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
这个清爽多了。
3、问题总结
原来python的strip函数有两种用法:
1)、如果省略参数,那么将会执行去除两端空格。如:
str=" abc "
print(str.strip()) #结果为abc
2)、如果传入了参数,那么将按照字符在两端去除相应字符,但这时候和空格没有任何关系。
str=" abc "
print(str.strip(" a")) #输出"bc"
print(str.strip("ac")) #输出" abc " 什么都没做
print(str.strip("a")) #输出" abc "什么都没做
按照官方文档的描述,第二个功能应该是在python2.2.3之后加上的。但这个设计真的很蹩脚。
之所以说是蹩脚,因为:
1)、不符合常理,已经说过了,你说要个字符串,那你就按照字符串计算呗,又非得按照字符处理。
2)、这种设计非常鸡肋,因为我们完全可以用其他途径来处理这个问题,你即使设计了,反而给大家带来使用的问题,误导大家,并且还这么隐蔽。
总体来说,python的strip真的很坑!