How to tell if function was passed a list or a string?

R

rh0dium

Hi All,

I have the nice little function (below) which used to work great
assuming the data[key] passed to it was a list. Well now I want to
update this a bit. I want this function to be smart enough to tell if
it's a list and do the funky concatonation otherwise don't.


def insert(self, table=None, data=None):
insert1=[]
insert2=[]

for key in data.keys():
insert1.append(key)
self.logger.debug("Key: %s Data: %s" % ( key,data[key]))
try:
an = []
for a in data[key]:
an.append(re.sub(",","", str(a)))
ans = string.join(an, ", ")
except:
ans = None
insert2.append(ans)

self.logger.info( "Insert command %s" % insert )
self.cursor.execute(insert)


The question is how do you tell that the data you were passed is a list
or not?


Thanks so much!
 
B

Ben Finney

rh0dium said:
I want this function to be smart enough to tell if it's a list and
do the funky concatonation otherwise don't.

Bad code smell. Don't try to be too clever with the data types passed
to you; instead, operate on them as though the caller has passed the
right thing.

Write unit tests and integration tests to ensure that the code is
behaving as expected, and to reduce the amount of clever code that
gets in the way of understanding the function.
The question is how do you tell that the data you were passed is a
list or not?

With difficulty, since strings are sequences. It's debatable whether
this is a wart.

Two options:

Use 'isinstance', which unfortunately breaks the rule of duck
typing. Currently there's no good duck-typing way to differentiate
strings from other sequences.

if isinstance(x, basestring):
# do string stuff
else:
# do sequence-of-string stuff

Or:

If you want to operate on sequences of strings, simply specify that's
all that can be passed and expect it inside your function. This is
more Pythonic, IMO.
 
R

Roy Smith

Ben Finney said:
Currently there's no good duck-typing way to differentiate
strings from other sequences.

I suppose you could do something like:

try:
foo.isalpha
except AttributeError:
print "foo is not a string"

but other than proving that you don't *have* to use isinstance(), I don't
think that approach has much going for it.
 
B

Ben Finney

Roy Smith said:
I suppose you could do something like:

try:
foo.isalpha
except AttributeError:
print "foo is not a string"

but other than proving that you don't *have* to use isinstance(), I
don't think that approach has much going for it.

Duck typing preserves one very important feature of Python: a class
doesn't have to *inherit from* type 'foo' to be a *substitute for*
type 'foo'. An 'isinstance' check will fail on objects that don't
inherit from the string types, but do implement the interface
adequately.

In this example, if an object 'x' implements the behaviour you're
going to use, but doesn't inherit from 'basestring', refusing it just
because 'isinstance(x, basestring)' is False would be the wrong
choice.
 
D

Daniel Nogradi

import types
type("") is types.ListType False
type("") is types.StringType True
type([]) is types.StringType False
type([]) is types.ListType
True

This is even worse than an 'isinstance' check; it refuses even
subclasses of the types you accept, breaking polymorphism *and*
inheritance.

And also note the following comment in the types module of the
standard library that was imported above:

# StringTypes is already outdated. Instead of writing "type(x) in
# types.StringTypes", you should use "isinstance(x, basestring)". But
# we keep around for compatibility with Python 2.2.
 
E

Edward Elliott

Roy said:
I suppose you could do something like:

try:
foo.isalpha
except AttributeError:
print "foo is not a string"

Another way:

if getattr (foo, 'isalpha', False):
print 'foo is a string'

Of course now string duck types must have an 'isalpha' and list ones can't,
but that shouldn't matter much.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top