Specifing arguments type for a function

P

Paolo Pantaleo

I have a function

def f(the_arg):
....

and I want to state that the_arg must be only of a certain type
(actually a list). Is there a way to do that?

Thnx
PAolo
 
D

Diez B. Roggisch

Paolo said:
I have a function

def f(the_arg):
...

and I want to state that the_arg must be only of a certain type
(actually a list). Is there a way to do that?

Yes and no. You can ensure that the passed object is a list, by calling e.g.

def f(arg):
if not isinstance(arg, list):
raise "Not a list!"


Alternatively, you can just use it as an iterable - and the exception will
come from arg not being iterable.

But what you can't do is make python complain about this:

def f(arg):
for e in arg:
print e


f(100)

before actually calling f. It will always fail at runtime.

Diez
 
R

Rony Steelandt

Paolo said:
Yes and no. You can ensure that the passed object is a list, by calling e.g.

def f(arg):
if not isinstance(arg, list):
raise "Not a list!"


Alternatively, you can just use it as an iterable - and the exception will
come from arg not being iterable.

But what you can't do is make python complain about this:

def f(arg):
for e in arg:
print e


f(100)

before actually calling f. It will always fail at runtime.

Diez

What about
def f(arg):
if type(arg)=='list':
#do something



--
---
Rony Steelandt
BuCodi
rony dot steelandt (at) bucodi dot com

Visit the python blog at http://360.yahoo.com/bucodi
 
B

bruno at modulix

Rony said:
What about
def f(arg):
if type(arg)=='list':

FWIW, type(<some_type>) returns a type object, not a string. So your
test will always fail. A right way to write this is:
if type(arg) is type([]):
...
#do something

Usually a very bad idea. It defeats the whole point of duck-typing. In
most cases, you don't care about the concrete class - all you want is an
object that implements an (implied) interface.

NB : I say 'usually' because there are a very few cases where testing
the concrete class can make sens - but there again, better to use
isinstance() than type().
 
M

Maric Michaud

Le Mardi 20 Juin 2006 12:29, Rony Steelandt a écrit :
What about
def f(arg):
    if type(arg)=='list':
        #do something

And if arg's type is subclass of list ?
The problem with isinstance is : and if arg is not of type list but is a
sequence (a instance of UserList for example) ?

The general case in python is duck typing, that means you define apis that
accept file-like object, iterables, dict-like (mapping) objects, string like
objects...

The problem with iterables is that they don't all implement the __iter__
attribute, for compatibility purpose the right test should be :

if not getattr(arg, '__iter__') and not getattr(arg, '__getitem__') :
raise ValueError('Function accepts only iterables') # or error handling
code


--
_____________

Maric Michaud
_____________

Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097
 
K

K.S.Sreeram

bruno said:
if type(arg) is type([]):

Just a tiny nitpick....
You can just use 'list' instead of 'type([])'

if type(arg) is list :
# blah blah


Regards
Sreeram


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.2 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFEl9xDrgn0plK5qqURApfbAJ4n3Fluokwk0545LsDP6TBfwcO/1ACgjI3E
FtSBYn8mx3WQge58BsSiekY=
=TRfL
-----END PGP SIGNATURE-----
 
M

Maric Michaud

Le Mardi 20 Juin 2006 13:28, Maric Michaud a écrit :
if not getattr(arg, '__iter__') and not getattr(arg, '__getitem__') :
    raise ValueError('Function accepts only iterables') # or error handling
code

oops, hasattr of course :

if not hasattr(arg, '__iter__') and not hasattr(arg, '__getitem__') :
raise ValueError('Function accepts only iterables') # or error handling

--
_____________

Maric Michaud
_____________

Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097
 
G

George Sakkis

Maric said:
Le Mardi 20 Juin 2006 13:28, Maric Michaud a écrit :

oops, hasattr of course :

if not hasattr(arg, '__iter__') and not hasattr(arg, '__getitem__') :
raise ValueError('Function accepts only iterables') # or error handling

This is ok - in theory. In practice I've found that e.g. strings are
more often than not handled as scalars although they are typically
iterables. Also tuples may or may not be considered as iterables,
depending on what they are used for. The definition of scalar is
application-dependent, that's why there is not an isscalar() builtin.

George
 
B

bruno at modulix

K.S.Sreeram said:
bruno said:
if type(arg) is type([]):


Just a tiny nitpick....
You can just use 'list' instead of 'type([])'

I know. Note that I wrote "*A* right way to write this", not "*The*
right way..."

And FWIW, you could also use arg.__class__ instead of type(arg).
 
M

Mike Duffy

Paolo said:
I have a function

def f(the_arg):
...

and I want to state that the_arg must be only of a certain type
(actually a list). Is there a way to do that?

I wrote a cool function decorator just for that purpose. It's posted on
the Python Decorator Library at:

http://wiki.python.org/moin/PythonDecoratorLibrary#head-308f2b3507ca91800def19d813348f78db34303e


If you use it, you will be able to simply write:

@accepts(list)
def f(the_arg):
...

and you will get a warning message if the_arg is not a list. Or, if you
want an exception raised, then just:

@accepts(list, debug=2)
def f(the_arg):
...

Let me know what you think, if you do end up using it. I'm eager for
feedback.
 
B

Bruno Desthuilliers

George Sakkis a écrit :
Maric Michaud wrote:




This is ok - in theory. In practice I've found that e.g. strings are
more often than not handled as scalars although they are typically
iterables. False

Also tuples may or may not be considered as iterables,
depending on what they are used for. False

The definition of scalar is
application-dependent, that's why there is not an isscalar() builtin.
 
G

George Sakkis

Dennis said:
It confirms that the object is indexable, and mutable -- ie; a list,
not a tuple or a string.

Ok, I'll try once more: What does __setitem__ have to do with
**iterability**, not mutability or indexability ? I was commenting on
Maric's post that although some objects are typically iterable, they
are often treated as atomic by some/many/most applications (e.g.
strings). It's not rocket science.

George
 
D

Dennis Lee Bieber

Ok, I'll try once more: What does __setitem__ have to do with
**iterability**, not mutability or indexability ? I was commenting on
Maric's post that although some objects are typically iterable, they
are often treated as atomic by some/many/most applications (e.g.
strings). It's not rocket science.
And the absence of the setitem would indicate such an object -- it
may be iterable in terms of retrieving subparts, but atomic WRT
modification.

That, at least, is how I interpreted the introduction of the test...
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
G

George Sakkis

Dennis said:
And the absence of the setitem would indicate such an object -- it
may be iterable in terms of retrieving subparts, but atomic WRT
modification.

That, at least, is how I interpreted the introduction of the test...

Applications that don't need to treat strings as iterables of
characters wouldn't do so even if strings were mutable. Atomicity has
to do with whether something is considered to be composite or not, not
whether it can be modified.

George
 
B

Bruno Desthuilliers

George said:
Ok, I'll try once more: What does __setitem__ have to do with
**iterability**, not mutability or indexability ?
Nothing.

I was commenting on
Maric's post that although some objects are typically iterable, they
are often treated as atomic by some/many/most applications (e.g.
strings). It's not rocket science.

No, it's not rocket science.

It's not rocket science neither to understand that, for the concrete
examples you used (ie strings and tuples), it's quite easy to detect'em
without testing the concrete type.

As you said, what is to be considered as scalar and what's to be
considered as sequence highly depends on the problem at hand. But doing
the distinction does not always implies testing concrete type or mro.
 
B

Bruno Desthuilliers

George said:
Applications that don't need to treat strings as iterables of
characters wouldn't do so even if strings were mutable. Atomicity has
to do with whether something is considered to be composite or not, not
whether it can be modified.

Sure. Do you have any generic solution for this ?
 

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

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top