测试一个对象是否是类字符串(类似的类)

声明:由于Python Cookbook第二版使用的是Python 2.X的版本,所以有些例子和结论在Python 3.X上无法直接使用。而这个书的第三版又跟这本书不同,听别人说这版本很好,而我拿这本书来学习,所以书上很多结论我都是直接拿过来写下来,只是更新为3.X版本的。但自己才疏学浅,(不是自谦)可能很多地方写得不对。还望得到纠正。

问题

有时候需要测试一个对象,尤其是当你在写一个函数或者方法的时候,经常要测试传入的参数是否一个字符串(或者更准确地说,这个对象是否具有类似于字符串的行为模式)

解决方案

给出一个利用内置的 isinstancestr 来简单快速地检查某个对象是否是字符串的方法。(书中还有一个是Unicode对象,但Python 3已经是Unicode编码方式了)

def isAString(obj):
    return isinstance(obj, str)

结果:

>>> isAString('Python')
True
>>> isAString('3.14')
True
>>> isAString(3.14)
False
>>> isAString('蟒蛇')
True

在书中, isinstance( obj, str )中的strbasestring。但 basestring在Python 3中已经用移除,用str代替。无论是ASCII码还是Unicode码,或者是基于str派生出来的任何类字符串的用户自定义类型都可以测试出。

但不幸的是,这个似乎完美的 isinstance 检查方案,对于 Python 标准库中的 collections模块的提供的UserString类的实例,完全无能为力。而 UserString 对象是非常明显的类字符串对象,只不过它不是从 str 派生出来的。用个例子:

>>> from collections import UserString

>>> like_string = UserString('abc')
>>> isAString(like_string)
False

如果要支持这种类型,可以直接检查一个对象的行为是否真的像字符串一样,比如:

def isStringLike(obj):
    try:
        obj + ''
    except:
        return False
    else:
        return True

这时候判断下,是可以返回True的:

>>> isStringLike(like_string)
True

这个 isStringLike()函数比方案中给出的isinstance()函数慢且复杂的多,但它的确使用于 UserString(以及其他的类字符串类型)的实例,也使用于 str 和 Unicode。

isStringLike函数中,引出一个Python里很有意思和很重要的概念:鸭子类型,这个并不是Python独有的,Ruby也有的鸭子类型。鸭子类型是多态机制的知识范畴。

Python中通常的类型检查方法是所谓的鸭子判断法:如果它走路像鸭子,叫声也像鸭子,那么对于我们的应用而言,就可以认为他就是鸭子了。isStringLike函数只不过检查了叫声部分,那其他的还不够。如果需要检查 obj对象的更多的类字符串特征,可以改造 try 子句,让它检查更多细节,比如:

try:
    obj.lower() + obj + ''

重点笔记:EAFP

进行类型验证(或者任何验证任务)的最具Python特色的方法是根据自己的预期去执行任务,在次过程中检测并处理由于不匹配产生的所有错误和异常。这是一个著名的处理方式,叫做“获得事后原谅总是比事先得到许可要容易的多”,简称EAFP。`try/except'是保证EAFP处理风格的关键工具。

你可能感兴趣的:(测试一个对象是否是类字符串(类似的类))