Reputation: 547
I'm trying to determine whether a function argument is a string, or some other iterable. Specifically, this is used in building URL parameters, in an attempt to emulate PHP's ¶m[]=val
syntax for arrays - so duck typing doesn't really help here, I can iterate through a string and produce things like ¶m[]=v¶m[]=a¶m[]=l
, but this is clearly not what we want. If the parameter value is a string (or a bytes? I still don't know what the point of a bytes actually is), it should produce ¶m=val
, but if the parameter value is (for example) a list, each element should receive its own ¶m[]=val
. I've seen a lot of explanations about how to do this in 2.* involving isinstance(foo, basestring)
, but basestring
doesn't exist in 3.*, and I've also read that isinstance(foo, str)
will miss more complex strings (I think unicode?). So, what is the best way to do this without causing some types to be lost to unnecessary errors?
Upvotes: 0
Views: 108
Reputation: 28846
You've been seeing things that somewhat conflict based on Python 2 vs 3. In Python 3, isinstance(foo, str)
is almost certainly what you want. bytes
is for raw binary data, which you probably can't include in an argument string like that.
The python 2 str
type stored raw binary data, usually a string in some specific encoding like utf8 or latin-1 or something; the unicode
type stored a more "abstract" representation of the characters that could then be encoded into whatever specific encoding. basestring
was a common ancestor for both of them so you could easily say "any kind of string".
In python 3, str
is the more "abstract" type, and bytes
is for raw binary data (like a string in a specific encoding, or whatever raw binary data you want to handle). You shouldn't use bytes
for anything that would otherwise be a string, so there's not a real reason to check if it's either str
or bytes
. If you absolutely need to, though, you can do something like isinstance(foo, (str, bytes))
.
Upvotes: 3