- 论坛徽章:
- 1
|
摘自 Python Cookbook
Credit: Luther Blissett
Problem
You need to test if an object, typically an argument to a
function or method you're writing, is a string (or more precisely, whether the
object is string-like).
Solution
A simple and fast way
to check whether something is a string or Unicode object is to use the built-ins
isinstance and basestring, as follows:
def isAString(anobj):
return isinstance(anobj, basestring)
Discussion
The first approach to solving this recipe's problem that comes
to many programmers' minds is type-testing:
def isExactlyAString(anobj):
return type(anobj) is type('')
However, this approach is pretty bad, as it willfully destroys
one of Python's greatest strengthssmooth, signature-based polymorphism. This
kind of test would reject Unicode objects, instances of user-coded subclasses of
str, and instances of any user-coded type that is meant to be
"string-like".
Using the isinstance built-in function, as recommended
in this recipe's Solution, is much better. The built-in type basestring
exists exactly to enable this approach. basestring is a common base
class for the str and unicode types, and any string-like type
that user code might define should also subclass basestring, just to
make sure that such isinstance testing works as intended.
basestring is essentially an "empty" type, just like object,
so no cost is involved in subclassing it.
Unfortunately, the canonical isinstance checking fails
to accept such clearly string-like objects as instances of the
UserString class from Python Standard Library module
UserString, since that class, alas, does not inherit from basestring. If you need to
support such types, you can check directly whether an object behaves like a
stringfor example:
def isStringLike(anobj):
try:
anobj + ''
except:
return False
else:
return True
This isStringLike function is slower and more
complicated than the isAString function presented in the "Solution",
but it does accept instances of UserString (and other string-like
types) as well as instances of str and unicode.
The general Python approach to
type-checking is known as duck typing: if it walks like a duck and quacks
like a duck, it's duck-like enough for our purposes. The isStringLike
function in this recipe goes only as far as the quacks-like part, but that may
be enough. If and when you need to check for more string-like features of the
object anobj, it's easy to test a few more properties by using a richer
expression in the TRy clausefor example, changing the clause to:
try: anobj.lower( ) + anobj + ''
In my experience, however, the simple test shown in the
isStringLike function usually does what I need.
The most Pythonic approach to type
validation (or any validation task, really) is just to try to perform whatever
task you need to do, detecting and handling any errors or exceptions that might
result if the situation is somehow invalidan approach known as "it's easier to
ask forgiveness than permission" (EAFP). try/except is the key
tool in enabling the EAFP style. Sometimes, as in this recipe, you may choose
some simple task, such as concatenation to the empty string, as a stand-in for a
much richer set of properties (such as, all the wealth of operations and methods
that string objects make available).
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/95893/showart_2066513.html |
|