473,320 Members | 1,909 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Object type check

Hi to all,

in statically-types languages, let's say C# for example, we use
polymorphism through interfaces. So we define an interface I with
method M and then a class C that implements I interface and write code
for the M method.
So, if we have a function that takes a parameter of type I, we know
before-hand that it will have an M method to call.

But in dynamic languages this is not the case and we can pass whatever
we want to that function. Assuming that someone writes a library in
Python that other programmers will use, what is the correct way to
check inside that function if the parameter passed is of the correct
type, maybe "isinstance" BIF ?

Thanks in advance!

Feb 7 '07 #1
16 2580
The answer is to do nothing at all. Use the interfaces of the objects
that you expect. Treat them like numbers if you expect them to be, or
stirngs, or iterables. Call methods and access attributes you expect
to be there. If the caller passes sometihng bad, and something doesn't
work, they'll find out about it and consult your documentation to see
what they did wrong. Dont restrict them to particular types. You would
not restrict them to a particular class in C#. Instead, you define the
interfaces simply by how you use the objects. This is called duck
typing (http://en.wikipedia.org/wiki/Duck_typing) which states "If it
walks like a duck and it quacks like a duck, it must be a duck." In
the end, isn't that what matters to you? Not the type or defined
interfaces of an object, but that it does what you expect.

On 7 Feb 2007 08:17:55 -0800, king kikapu <ab********@panafonet.grwrote:
Hi to all,

in statically-types languages, let's say C# for example, we use
polymorphism through interfaces. So we define an interface I with
method M and then a class C that implements I interface and write code
for the M method.
So, if we have a function that takes a parameter of type I, we know
before-hand that it will have an M method to call.

But in dynamic languages this is not the case and we can pass whatever
we want to that function. Assuming that someone writes a library in
Python that other programmers will use, what is the correct way to
check inside that function if the parameter passed is of the correct
type, maybe "isinstance" BIF ?

Thanks in advance!

--
http://mail.python.org/mailman/listinfo/python-list

--
Read my blog! I depend on your acceptance of my opinion! I am interesting!
http://ironfroggy-code.blogspot.com/
Feb 7 '07 #2
On Feb 7, 5:17 pm, "king kikapu" <aboudou...@panafonet.grwrote:
Hi to all,

in statically-types languages, let's say C# for example, we use
polymorphism through interfaces. So we define an interface I with
method M and then a class C that implements I interface and write code
for the M method.
So, if we have a function that takes a parameter of type I, we know
before-hand that it will have an M method to call.

But in dynamic languages this is not the case and we can pass whatever
we want to that function. Assuming that someone writes a library in
Python that other programmers will use, what is the correct way to
check inside that function if the parameter passed is of the correct
type, maybe "isinstance" BIF ?
Usually, you don't check anything at all. However, in some cases, it
may make
sense to check that you passed the right object.
For instance if you have the container

class Example(object):
def __init__(self, innerobj):
self.innerobj = innerobj
def amethod(self):
self.innerobj.amethod()

ex = Example(None)

you will get an error only when calling ex.amethod(). If you are going
to call
ex.amethod() one hour after instantiation, you will get the error too
late.
So, it makes sense to put a check in the __init__ method, something
like

assert hasattr(self.innerobj, 'amethod')

in order to get an error message as soon as possible. Notice that
checking for the existance
of the needed method is better than using isinstance, since it gives
you much more
freedom for innerobj. Do not require more than you need.
HTH,

Michele Simionato

Feb 7 '07 #3
Dont restrict them to particular types. You would
not restrict them to a particular class in C#. Instead, you define the
interfaces simply by how you use the objects.
Of cource i restrict them to particular types! In C# you cannot pass
something bad
this way because the compiler will just catch it!

I see what you mean by "duck typing". So you suggest the "do nothing
at all" direction,
better document my code so other can see what is expected, right ?

Feb 7 '07 #4
On 7 Feb 2007 08:59:12 -0800, king kikapu <ab********@panafonet.grwrote:
Dont restrict them to particular types. You would
not restrict them to a particular class in C#. Instead, you define the
interfaces simply by how you use the objects.

Of cource i restrict them to particular types! In C# you cannot pass
something bad
this way because the compiler will just catch it!
No, you restrict the interfaces, in your example, not the classes. It
is the same in python, but the interfaces are implicitly defined by
how you use the objects.
I see what you mean by "duck typing". So you suggest the "do nothing
at all" direction,
better document my code so other can see what is expected, right ?
Yes. Also, remember that this means if you write code to expect a
dictionary, any mapping type that supports the operations and methods
you use will work transparently, allowing your code to be much more
flexible.

--
Read my blog! I depend on your acceptance of my opinion! I am interesting!
http://ironfroggy-code.blogspot.com/
Feb 7 '07 #5
Of cource i restrict them to particular types! In C# you cannot pass
something bad
this way because the compiler will just catch it!
And you cant pass something 'good' that immitates another object
interface (a file-like object for example)
I see what you mean by "duck typing". So you suggest the "do nothing
at all" direction,
better document my code so other can see what is expected, right ?
I would add UnitTests to it.
--
EduardoOPadoan (eopadoan->altavix::com)
Feb 7 '07 #6
king kikapu a écrit :
Hi to all,

in statically-types languages, let's say C# for example, we use
polymorphism through interfaces. So we define an interface I with
method M and then a class C that implements I interface and write code
for the M method.
So, if we have a function that takes a parameter of type I, we know
before-hand that it will have an M method to call.

But in dynamic languages this is not the case and we can pass whatever
we want to that function.
Yes. And this is a Good Thing (tm).
Assuming that someone writes a library in
Python that other programmers will use, what is the correct way to
check inside that function if the parameter passed is of the correct
type, maybe "isinstance" BIF ?
The correct way in Python is to *not* check. Just document what kind of
interface you expect, and it's ok. If the people using your code are stupid
and lazy enough to not read the doc, then you can't help .

Feb 7 '07 #7
king kikapu a écrit :
>>Dont restrict them to particular types. You would
not restrict them to a particular class in C#. Instead, you define the
interfaces simply by how you use the objects.


Of cource i restrict them to particular types! In C# you cannot pass
something bad
this way because the compiler will just catch it!
This won't prevent some stupid to implement the interface with a totally
different semantic (what about some getter wiping out your hard drive ?).

FWIW, in Python, you can't pass something bad because it will raise an
exception. Well, to be true, there's *one* gotcha : passing a string
where a list or tuple is expected may in some occasions yield strange
results (strings being sequences too).
I see what you mean by "duck typing". So you suggest the "do nothing
at all" direction,
better document my code so other can see what is expected, right ?
Exactly.
Feb 7 '07 #8
at first, thanks you all for your help!

So, i will follow your advice.In a moment though, i thought that "ok,
do not check anything of the parameter's type but do a try/catch at
the calls inside the function"

But this way, i would rather defeat the purpose because i have to try/
catch in *every* call inside the func.
So, i suppose that i wouldn't want to do that and just try to make the
call in whatever they passed me in.

Strange world the dynamic one....

Feb 7 '07 #9
king kikapu a écrit :
at first, thanks you all for your help!

So, i will follow your advice.In a moment though, i thought that "ok,
do not check anything of the parameter's type but do a try/catch at
the calls inside the function"
And so what ? Once an exception got caught, what are you going to do ?
Raise another exception ? Re-raise the same exception ? In both cases, you
usually don't gain much - and sometimes loose (time, simplicity,
readability, and
a usefull traceback).

Unless you know how to handle it, it's usually better to let the exception
propagate. Usually, the person coding the *application* (ie: the coder using
your lib) will wrap the whole thing into a catch-all exception handler
at the higher level,
so he can log the full traceback, display a nice error to the end user,
and crash gracefully.
As a library programmer, you should not care about this.
But this way, i would rather defeat the purpose because i have to try/
catch in *every* call inside the func.
So, i suppose that i wouldn't want to do that and just try to make the
call in whatever they passed me in.
You're starting to see the light, my friend !-)
Strange world the dynamic one....
If that's too dynamic for you, then run for your life - this is just the
visible
part of the iceberg.
Feb 7 '07 #10
And so what ? Once an exception got caught, what are you going to do ?

You have absolutely right, that's the reason i rejected this.
You're starting to see the light, my friend !-)
Strange world the dynamic one....

If that's too dynamic for you, then run for your life

Hehe...you know, it is a little bit strange if you are used to Delphi,
C# or any other statically-typed language and suddenly you starting
programming in a dynamic one, really strange! :)
All of the efforts all these years to declare everything correct, to
fight with the compiler (and to always have him win...), to ...[put
whatever here] and now Python...What can i say!...

Thanks for the help!

Feb 7 '07 #11
king kikapu a écrit :
>>And so what ? Once an exception got caught, what are you going to do ?


You have absolutely right, that's the reason i rejected this.
hear hear !-)

( snip)
All of the efforts all these years to declare everything correct, to
fight with the compiler (and to always have him win...), to ...[put
whatever here] and now Python...What can i say!...
http://www.lesher.ws/choose_python.pdf

Feb 7 '07 #12
On Wed, 07 Feb 2007 08:59:12 -0800, king kikapu wrote:
I see what you mean by "duck typing". So you suggest the "do nothing
at all" direction,
better document my code so other can see what is expected, right ?
Generally speaking, yes, but not always.

The usual Python model is "better to ask forgiveness than permission". For
example, these two snippets of code do (more or less) the same thing, but
the second is more in the Pythonic style:
# Look Before You Leap
if isinstance(x, SomeClass):
x.somemethod()
else:
do_something_else()

# Better To Ask For Forgiveness Than Permission
try:
x.somemethod()
except AttributeError: # no such method exists
do_something_else()
Setting up a try...except block is cheap in Python, so it costs very
little to try calling the method, then take a different action only if it
is one of the rare failures. (However, catching the exception is
expensive, so if you have lots of failures, you might want to rethink your
strategy.)

But sometimes this isn't what you want. Here's a counter example:

def modify(list_of_x):
for x in list_of_x:
x.change_in_place()

Note that there's no "do_something_else" to do if an item doesn't have
the correct method. That's bad data, and no recovery is possible, so
you just let the exception propagate. But there's a problem: if the
calling code catches the exception, as it may, you leave the list_of_x
in an intermediate state where some of the items have been changed and
some haven't.

The solution is a form of Look Before You Leap that doesn't break
duck-typing:

def modify(list_of_x):
for x in list_of_x:
try:
x.change_in_place # don't call the method, just check it exists
# we can check as many or as few methods as we need, e.g.:
x.__getitem__ # check that x is indexable
except AttributeError:
raise ValueError("list contains an invalid item")
# if we get here, we know it is safe to proceed
for x in list_of_x:
x.change_in_place()

Now each item doesn't have to be an instance of SomeClass, but merely
needs to have the right signature.
--
Steven D'Aprano

Feb 8 '07 #13
def modify(list_of_x):
for x in list_of_x:
try:
x.change_in_place # don't call the method, just check it exists
XXmmmm...what exactly is going on here ? I mean, what is actually
happens if you omit the parenethesis as you just did ? I understand
that it does not call the method, but what is really doing ??

Feb 8 '07 #14
On Feb 8, 12:00 pm, "king kikapu" <aboudou...@panafonet.grwrote:
def modify(list_of_x):
for x in list_of_x:
try:
x.change_in_place # don't call the method, just check it exists

XXmmmm...what exactly is going on here ? I mean, what is actually
happens if you omit the parenethesis as you just did ? I understand
that it does not call the method, but what is really doing ??
See http://users.rcn.com/python/download/Descriptor.htm for more than
you ever wanted
to know about attribute access in Python.

Michele Simionato

Feb 8 '07 #15

Ï/Ç Michele Simionato Ýãñáøå:
See http://users.rcn.com/python/download/Descriptor.htm for more than
you ever wanted
to know about attribute access in Python.

Michele Simionato
Great stuff Michele, thanks!

Feb 8 '07 #16
On Thu, 08 Feb 2007 03:00:39 -0800, king kikapu wrote:
>def modify(list_of_x):
for x in list_of_x:
try:
x.change_in_place # don't call the method, just check it exists

XXmmmm...what exactly is going on here ? I mean, what is actually
happens if you omit the parenethesis as you just did ? I understand
that it does not call the method, but what is really doing ??
The same as for any attribute: x.name gives the object referred to by the
attribute name, and x.name() calls that object.

He's a simple example:
>>def foo():
.... return "foo"
....
>>type(foo) # the name alone
<type 'function'>
>>type(foo()) # call the function
<type 'str'>
--
Steven.

Feb 9 '07 #17

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Hazz | last post by:
In this sample code of ownerdraw drawmode, why does the '(ComboBox) sender' line of code need to be there in this event handler? Isn't cboFont passed via the managed heap, not the stack, into this...
39
by: eruanion | last post by:
Hi, I've been working on this for a while now and I can't seem to find out what is wrong with my code. I have 2 files one c3common.js which only contains javascript functions for my main html page...
13
by: Fredrik Strandberg | last post by:
Hi! I receive an object as a System.Object argument to a method. I need to check if the object is a Type object or not (that is, not a specific type, but if the object is a type object in...
4
by: Greg | last post by:
I'm guessing the problem I'm having has something to do with Master Pages or DetailsView because the exact same code works fine on a page without a Master Page and DetailsView controls. The...
6
by: tommaso.gastaldi | last post by:
Hi, does anybody know a speedy analog of IsNumeric() to check for strings/chars. I would like to check if an Object can be treated as a string before using a Cstr(), clearly avoiding the time...
7
by: runsun pan | last post by:
I wanna check if an object is the *arguments* object of a function, is that possible? When we do: typeof(arguments) it always returns "object", doesn't seem to be helpful.
21
by: phpCodeHead | last post by:
Code which should allow my constructor to accept arguments: <?php class Person { function __construct($name) { $this->name = $name; } function getName()
8
by: Brad Pears | last post by:
I want to check to see if a particular object exists using vb.net 2005. I have a class called clsContract. When the user clicks the 'New Contract' button, I want to check to see if a clsContract...
2
by: bips2008 | last post by:
The code seems to work fine in other browser but in IE it throws this error. This is very urgent for me and any help would be greatly appreciated For your convienence i have posted the code for the...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.