Re: sufficiently pythonic code for testing type of function

2006-10-16 Thread Bruno Desthuilliers
Fredrik Lundh wrote:
 Scott David Daniels wrote:
 
 Nope.  idempotent: f(f(x)) = f(x)
 That is, after doing it once, repeating it won't hurt.
 
 http://en.wikipedia.org/wiki/Idempotence_%28computer_science%29
 
 /F
 
Thank you (Scott and Fredrik) for the correction.

-- 
bruno desthuilliers
python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '[EMAIL PROTECTED]'.split('@')])
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: sufficiently pythonic code for testing type of function

2006-10-13 Thread Theerasak Photha
On 10/11/06, Bruno Desthuilliers [EMAIL PROTECTED] wrote:
 Theerasak Photha wrote:
  On 10/11/06, Fredrik Lundh [EMAIL PROTECTED] wrote:
 
  can be a lot better than a 30-level traceback that ends with a line
  looking something like
 
   fnut.index(gah)
 
  Despite long experience with Perl, I am not a big follower of the
  goose_level: blah method of error reporting...
 
  also, checking for __method__ is, in general, not the right way to check
  if an object implements a given interface.
 
  I had a vague feeling it might not be a Right Thing(tm).
  flame-proof-underwearI kind of miss
  responds_to?/flame-proof-underwear

 getattr(obj, name[,default]) is your friend. Remember that methods are
 just callable attributes.

I am familiar with getattr from the Introspection material in Dive
into Python of course.

Earlier in the thread we decided that using getattr is the Wrong
Way(tm) to decide whether an object has such and such operation
(respond_to?) because implementation details can hide this.

So I learned the best thing to do is Suck It And See (an electrical
joke, not a penis joke, BION) aka EAFP.

I just found out Ruby isn't much better in this regard:

class Foo
  def self.method_missing(meth, *args)
puts meth
  end
end

Foo.bar()
puts Foo.respond_to?(:bar)

===
bar
false

WTF?

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


Re: sufficiently pythonic code for testing type of function

2006-10-13 Thread Scott David Daniels
Bruno Desthuilliers wrote:
 ... idempotent - no side effects.

Nope.  idempotent: f(f(x)) = f(x)
That is, after doing it once, repeating it won't hurt.

--Scott David Daniels
[EMAIL PROTECTED]
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: sufficiently pythonic code for testing type of function

2006-10-13 Thread Fredrik Lundh
Scott David Daniels wrote:

 Nope.  idempotent: f(f(x)) = f(x)
 That is, after doing it once, repeating it won't hurt.

http://en.wikipedia.org/wiki/Idempotence_%28computer_science%29

/F

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


Re: sufficiently pythonic code for testing type of function

2006-10-12 Thread A.T.Hofkamp
On 2006-10-11, Bruno Desthuilliers [EMAIL PROTECTED] wrote:
 A.T.Hofkamp wrote:
 On 2006-10-11, Bruno Desthuilliers [EMAIL PROTECTED] wrote:
 Now the real question : what if the object is not an instance of any of
 the types, but still support the expected interface ?

 
 one possible answer: Use ZopeInterfaces
 (and ask objects 'do you implement interface X' rather than 'are you type Y')
 
 Not sure what options you have when dealing with builtin data types however.

 This was mostly a rethorical question...

And even for rethorical questions, Python already provides a solution.. :-)

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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread John Machin
Theerasak Photha wrote:
 I wrote this for someone else to take an object and list of types,
 then check if obj is one of those types, raising an error otherwise.

 Is it enough to rely on side effects or absence thereof, or should I
 put return True in here somewhere?

 def test_obj_type(obj, types):
   for type in types:
 if isinstance(obj, type):
   break
 else:
   raise ValueError, 'object is not in %s' % types


Hello Theerasak,

To answer your question: Either (a) return True if OK, False if not OK
or (b) make it like an assertion: raise an exception if not OK, do
nothing if OK. Returning True from the above function would be a rather
strange hybrid.

However:

1. if isinstance(obj, types[1] is true, but isinstance(obj, types[0])
is false, this would appear to raise ValueError. Is the indentation of
the else and raise what you intended?

2. In any case, since Python 2.2, no loop is necessary:

def test_obj_type(obj, types):
if not isinstance(obj, types):
raise ValueError, 'object is not in %s' % (types, )

If you don't want the assertion style, your someone else can call
isinstance directly.

3. And please notice the change in the raise line; if types is a tuple
of two or more items, the % operator treats it specially. As coded, you
would get this exception:
TypeError: not all arguments converted during string formatting

HTH,
John

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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Ben Finney
Theerasak Photha [EMAIL PROTECTED] writes:

 I wrote this for someone else to take an object and list of types,
 then check if obj is one of those types, raising an error otherwise.

This is a way of programming known as Look Before You Leap (LBYL).
It is most likely a mistake to do this in Python. (That's not an
absolute, but it's the smart way to bet.)

Far better is to take the objects passed, *use* them in the way that
you need to use them, and catch exceptions that get raised at the
point where there is enough context to handle them. This is the
Easier to Ask Forgiveness than Permission (EAFP) principle, and it
is considered to be far more Pythonic.

URL:http://jaynes.colorado.edu/PythonIdioms.html

-- 
 \   Prediction is very difficult, especially of the future.  -- |
  `\Niels Bohr |
_o__)  |
Ben Finney

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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Ben Finney
Theerasak Photha [EMAIL PROTECTED] writes:

 On 10/11/06, Ben Finney [EMAIL PROTECTED] wrote:
  Why have you re-implemented (a less-functional version of) 'isinstance'?

 Ignorance, I think. But the issue is resolved now. Thank you.

Hopefully it is also merely ignorance that leads you to such obsessive
type-checking.

Here's a discussion on EAFP versus LBYL that gets a lot of Google juice.

URL:http://mail.python.org/pipermail/python-list/2003-May/163820.html

-- 
 \ I planted some bird seed. A bird came up. Now I don't know |
  `\   what to feed it.  -- Steven Wright |
_o__)  |
Ben Finney

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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Theerasak Photha
On 10/11/06, Ben Finney [EMAIL PROTECTED] wrote:
 Theerasak Photha [EMAIL PROTECTED] writes:

 Far better is to take the objects passed, *use* them in the way that
 you need to use them, and catch exceptions that get raised at the
 point where there is enough context to handle them. This is the
 Easier to Ask Forgiveness than Permission (EAFP) principle, and it
 is considered to be far more Pythonic.

Again, someone asked me to write the code for him in a personal
response to a previous thread. I simply executed his wishes (albeit
poorly).

I knew about EAFP before Python; in Ruby we have 'duck typing' and
there's a whole chapter about its virtues in Pick Axe. Myself I am a
strong proponent of this method, also known in OO Perl lingo, which I
know well, as interface polymorphism (Conway).

The main reason I *didn't* grok isinstance was b/c I never really
thought to use it before... :)

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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Theerasak Photha
On 10/11/06, Ben Finney [EMAIL PROTECTED] wrote:
 Theerasak Photha [EMAIL PROTECTED] writes:

  On 10/11/06, Ben Finney [EMAIL PROTECTED] wrote:
   Why have you re-implemented (a less-functional version of) 'isinstance'?
 
  Ignorance, I think. But the issue is resolved now. Thank you.

 Hopefully it is also merely ignorance that leads you to such obsessive
 type-checking.

It would seem I clicked the Send button late. **Too slow!!** :)

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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Bruno Desthuilliers
Theerasak Photha wrote:
 I wrote this for someone else to take an object and list of types,
 then check if obj is one of those types, 

This is already what isinstance(obj, tuple_of_types) does.

 raising an error otherwise.
 
 Is it enough to rely on side effects or absence thereof, or should I
 put return True in here somewhere?

What for ?

 def test_obj_type(obj, types):
  for type in types:
if isinstance(obj, type):
  break
else:
  raise ValueError, 'object is not in %s' % types



def checkinstanceof(obj, types):
  if not isinstance(obj, types):
raise ValueError('object is not an instance of %s' % str(types))


Now the real question : what if the object is not an instance of any of
the types, but still support the expected interface ?

 -- Theerasak


-- 
bruno desthuilliers
python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '[EMAIL PROTECTED]'.split('@')])
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Theerasak Photha
On 10/11/06, Bruno Desthuilliers [EMAIL PROTECTED] wrote:

 Now the real question : what if the object is not an instance of any of
 the types, but still support the expected interface ?

Perhaps:

try:
  for attribute in ['foo', 'bar', '__baz__']:
getattr(mystery_object, '__%s__' % attribute)
except AttributeError:
  # Do sumthin bout it

Is it wrong to 're-raise' an exception with application-specific
details within an except clause?

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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Fredrik Lundh
Theerasak Photha wrote:

 Now the real question : what if the object is not an instance of any of
 the types, but still support the expected interface ?
 
 Perhaps:
 
 try:
   for attribute in ['foo', 'bar', '__baz__']:
 getattr(mystery_object, '__%s__' % attribute)
 except AttributeError:
   # Do sumthin bout it
 
 Is it wrong to 're-raise' an exception with application-specific
 details within an except clause?

nope, as long as the new exception is provides more accurate information 
about what actually happened.  something like

 try:
 do something
 except ValueError:
 raise RuntimeError(the frobnitz failed to catch the kitten)

can be a lot better than a 30-level traceback that ends with a line 
looking something like

 fnut.index(gah)

on the other hand, things like this are all too common:

try:
do something
except:
raise Exception(something happened)

also, checking for __method__ is, in general, not the right way to check 
if an object implements a given interface.  some types use C-level slots 
or alternative hooks to provide functionality, and such things are not 
always visible from the outside (Python knows how to use them, though).

so if you can, try doing the operation instead, and catch error (if you 
really need to check first, use an idempotent operation, if available).

/F

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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Theerasak Photha
On 10/11/06, Fredrik Lundh [EMAIL PROTECTED] wrote:

 can be a lot better than a 30-level traceback that ends with a line
 looking something like

  fnut.index(gah)

Despite long experience with Perl, I am not a big follower of the
goose_level: blah method of error reporting...

 also, checking for __method__ is, in general, not the right way to check
 if an object implements a given interface.

I had a vague feeling it might not be a Right Thing(tm).
flame-proof-underwearI kind of miss
responds_to?/flame-proof-underwear

 so if you can, try doing the operation instead, and catch error (if you
 really need to check first, use an idempotent operation, if available).

I'll do that as soon as my green noggin figures out what 'idempotent' means.

Serves me right for being a liberal arts weenie:
http://www.c2.com/cgi/wiki?ThaiLanguage

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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Fredrik Lundh
Theerasak Photha wrote:

 I'll do that as soon as my green noggin figures out what 'idempotent' means.

Acting as if used only once, even if used multiple times, to quote
the first explanation I saw on the google result page.

and from the irony department, googling for indempotent provides an 
even clearer explanation: Refers to an operation that produces the same 
results no matter how many times it is performed.

/F

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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Bruno Desthuilliers
Theerasak Photha wrote:
 On 10/11/06, Fredrik Lundh [EMAIL PROTECTED] wrote:
 
 can be a lot better than a 30-level traceback that ends with a line
 looking something like

  fnut.index(gah)
 
 Despite long experience with Perl, I am not a big follower of the
 goose_level: blah method of error reporting...
 
 also, checking for __method__ is, in general, not the right way to check
 if an object implements a given interface.
 
 I had a vague feeling it might not be a Right Thing(tm).
 flame-proof-underwearI kind of miss
 responds_to?/flame-proof-underwear

getattr(obj, name[,default]) is your friend. Remember that methods are
just callable attributes.

 so if you can, try doing the operation instead, and catch error (if you
 really need to check first, use an idempotent operation, if available).
 
 I'll do that as soon as my green noggin figures out what 'idempotent'
 means.

idempotent - no side effects.

-- 
bruno desthuilliers
python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '[EMAIL PROTECTED]'.split('@')])
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread A.T.Hofkamp
On 2006-10-11, Bruno Desthuilliers [EMAIL PROTECTED] wrote:

 Now the real question : what if the object is not an instance of any of
 the types, but still support the expected interface ?


one possible answer: Use ZopeInterfaces
(and ask objects 'do you implement interface X' rather than 'are you type Y')

Not sure what options you have when dealing with builtin data types however.


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


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread Bruno Desthuilliers
A.T.Hofkamp wrote:
 On 2006-10-11, Bruno Desthuilliers [EMAIL PROTECTED] wrote:
 Now the real question : what if the object is not an instance of any of
 the types, but still support the expected interface ?

 
 one possible answer: Use ZopeInterfaces
 (and ask objects 'do you implement interface X' rather than 'are you type Y')
 
 Not sure what options you have when dealing with builtin data types however.

This was mostly a rethorical question...


-- 
bruno desthuilliers
python -c print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in '[EMAIL PROTECTED]'.split('@')])
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: sufficiently pythonic code for testing type of function

2006-10-11 Thread bruno de chez modulix en face

Theerasak Photha a écrit :

 On 10/11/06, Bruno Desthuilliers [EMAIL PROTECTED] wrote:

  Now the real question : what if the object is not an instance of any of
  the types, but still support the expected interface ?

 Perhaps:

 try:
   for attribute in ['foo', 'bar', '__baz__']:
 getattr(mystery_object, '__%s__' % attribute)
 except AttributeError:
   # Do sumthin bout it

Isn't this a case of useless overcomplexification ? Since you end up
raising an exception, why not just assume the object is ok and let
Python raise the exception for you if it is not ? From the client code
POV, it doesn't make much difference !-)


 Is it wrong to 're-raise' an exception with application-specific
 details within an except clause?

Nope - as long as you provide more details (or more helpful details)
*and* do not loose/mask/whatever useful infos from the original
exception.

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


sufficiently pythonic code for testing type of function

2006-10-10 Thread Theerasak Photha
I wrote this for someone else to take an object and list of types,
then check if obj is one of those types, raising an error otherwise.

Is it enough to rely on side effects or absence thereof, or should I
put return True in here somewhere?

def test_obj_type(obj, types):
  for type in types:
if isinstance(obj, type):
  break
else:
  raise ValueError, 'object is not in %s' % types

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


Re: sufficiently pythonic code for testing type of function

2006-10-10 Thread Fredrik Lundh
Theerasak Photha wrote:

 I wrote this for someone else to take an object and list of types,
 then check if obj is one of those types, raising an error otherwise.

note that a call to your function is pretty much equivalent to

assert isinstance(obj, types)

which has the additional advantage that you can provide a more specific 
message:

assert isinstance(obj, types), message

and also disable the check once you've verified that the code actually 
does the right thing.

/F

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


Re: sufficiently pythonic code for testing type of function

2006-10-10 Thread Ben Finney
Theerasak Photha [EMAIL PROTECTED] writes:

 I wrote this for someone else to take an object and list of types,
 then check if obj is one of those types, raising an error otherwise.

 Is it enough to rely on side effects or absence thereof, or should I
 put return True in here somewhere?

 def test_obj_type(obj, types):
   for type in types:
 if isinstance(obj, type):
   break
 else:
   raise ValueError, 'object is not in %s' % types

Why have you re-implemented (a less-functional version of) 'isinstance'?

 help(isinstance)
Help on built-in function isinstance in module __builtin__:

isinstance(...)
isinstance(object, class-or-type-or-tuple) - bool

Return whether an object is an instance of a class or of a subclass 
thereof.
With a type as second argument, return whether that is the object's 
type.
The form using a tuple, isinstance(x, (A, B, ...)), is a shortcut for
isinstance(x, A) or isinstance(x, B) or ... (etc.).

 isinstance(3, (int, float))
True

-- 
 \   Yesterday I told a chicken to cross the road. It said, 'What |
  `\  for?'  -- Steven Wright |
_o__)  |
Ben Finney

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


Re: sufficiently pythonic code for testing type of function

2006-10-10 Thread Theerasak Photha
On 10/11/06, Ben Finney [EMAIL PROTECTED] wrote:

 Why have you re-implemented (a less-functional version of) 'isinstance'?

Ignorance, I think. But the issue is resolved now. Thank you.

http://www.stanford.edu/~spqrsyc/crew/crew%20-%20ignorance.gif

It's amazing how much easier it is for a team to work together when
no one has any idea where they're going :)

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