Python中测试一个对象是否为字符串

有时候需要测试一个对象,尤其是你写一个函数和方法,经常要测试传入的参数是否是一个字符串,如果采用了其他语言的类似的处理方式,测试传入参数的类型type(),通常就是这么写:

>>> def isString(obj):
	return type(obj) is type()
>>> isString(Hello)
True
>>> isString([1, 2, 3, 4])
False

上面的处理方式至少有三个错误:

1) Unicode对象无法通过测试

>>> def isString(obj):
...     return type(obj) is type()
...
>>> isString(uaaa)
False

2) 用户自己编写的str子类通不过测试

>>> class ClassTest(object):
	def __str__(self):
		return "THIS IS CLASS TEST!"
>>> def isString(obj):
	return type(obj) is type()
>>> ct = ClassTest()
>>> str(ct)
THIS IS CLASS TEST!
>>> isString(ct)
False

3) 最重要的是破坏了Python最重要,强大的特性的:多态机制!

>>> 4 *4
4444
>>> 4 * 4
16
>>>

多态机制的机制,是Python的一个非常非常重要的特性,比如像上面的如果是字符串4*4,则Python识别这个是字符串的对象,字符串对象*4,则是4个4,如果是整数4,则4 * 4,得出的结果则是16,像上面的例子其实有很多,这是Python强大的源泉,如果使用type()进行判断,则无形中破坏了Python最为强大,最为平滑,最为灵活的多态进制!!!

所以基于上面的的缺陷,理想的方式是,即可检查字符串和自己定义的str,又可以检查Unicode对象,还不会破坏Python的多态机制,可以这么写:

>>> def isString(obj):
...     try:
...             obj + 
...     except:
...             return False
...     else:
...             return True
...
>>> isString(u"Hello,World!")
True

上面的方法就是著名的"鸭子判断法",如果是鸭子,那么它就一定具备鸭子的特征!比如说字符串,它必定可以使用一个字符串和空字符串来做合并操作,也有lower(),title()等方法。

>>> "ABCD" + " "
ABCD 
>>> "ABCD".lower()
abcd
>>> hello.title()
Hello

所以完美的写法就是多检查一些其他细节,特征! 比如鸭子,判断它走路是否像鸭子,叫声是否像鸭子!

>>> def isString(obj):
...     try:
...         obj.lower() + obj.title() + obj + ""
...     except:
...         return False
...     else:
...         return True
...
>>> isString("Hello ")
True
>>> isString(u"Hello")
True

经验分享 程序员 微信小程序 职场和发展