Is except: ... pass bad style?

M

marduk

I commonly use code like this

try:
# call optional method
myobj.method()
except AttributeError:
# no biggie
pass


Occasionally I use pylint, which is a good tool, but in the above
snippet pylint will complain that 'Except doesn't do anything'. True,
but is that bad style? I know there are other ways of doing it, but
of all the other "obvious" ones, this appears the most straight
forward.

Should I ignore pylint or is there a more Pythonic way to do this?
 
M

Michael Hudson

marduk said:
I commonly use code like this

try:
# call optional method
myobj.method()
except AttributeError:
# no biggie
pass


Occasionally I use pylint, which is a good tool, but in the above
snippet pylint will complain that 'Except doesn't do anything'. True,
but is that bad style? I know there are other ways of doing it, but
of all the other "obvious" ones, this appears the most straight
forward.

Sounds like a dubious warning to me.
Should I ignore pylint or is there a more Pythonic way to do this?

Well,

try:
meth = myobj.method
except AttributeError:
pass
else:
meth()

is possibly better (your version might hide bugs in the method). It's
a pain to do this all the time, though.

Come to think of it

getattr(myobj, "method", lambda :None)()

also acheives the same thing. Bit inscrutable, though.

Cheers,
mwh
 
A

Alex Martelli

marduk said:
I commonly use code like this

try:
# call optional method
myobj.method()
except AttributeError:
# no biggie
pass


Occasionally I use pylint, which is a good tool, but in the above
snippet pylint will complain that 'Except doesn't do anything'. True,
but is that bad style? I know there are other ways of doing it, but
of all the other "obvious" ones, this appears the most straight
forward.

Should I ignore pylint or is there a more Pythonic way to do this?

I would prefer:

try: themethod = myobj.method
except AttributeError: pass
else: themethod()

but this, too, has an empty except body, which IS pretty normal...


Alex
 
A

Aahz

I commonly use code like this

try:
# call optional method
myobj.method()
except AttributeError:
# no biggie
pass

Occasionally I use pylint, which is a good tool, but in the above
snippet pylint will complain that 'Except doesn't do anything'. True,
but is that bad style? I know there are other ways of doing it, but
of all the other "obvious" ones, this appears the most straight
forward.

Should I ignore pylint or is there a more Pythonic way to do this?

Neither. It's a perfectly good Pythonic idiom, but it's also likely to
be programmer error (mocking up the try/except structure and forgetting
to fill in the blanks later). So you should ignore pylint when it's
code you're familiar with (and have already double-checked your
intentions), but you should pay attention to pylint when you're writing
new code and checking it.
 
T

Thomas Heller

marduk said:
I commonly use code like this

try:
# call optional method
myobj.method()
except AttributeError:
# no biggie
pass


Occasionally I use pylint, which is a good tool, but in the above
snippet pylint will complain that 'Except doesn't do anything'. True,
but is that bad style? I know there are other ways of doing it, but
of all the other "obvious" ones, this appears the most straight
forward.

Should I ignore pylint or is there a more Pythonic way to do this?

It's better to write it this way, imo:

try:
mth = myobje.method
except AttributeError:
pass
else:
mth()

Otherwise you cannot determine whether myobj doesn't have this method,
or the method call is raising an exception.

Thomas
 
P

Peter Otten

marduk said:
I commonly use code like this

try:
# call optional method
myobj.method()
except AttributeError:
# no biggie
pass


Occasionally I use pylint, which is a good tool, but in the above
snippet pylint will complain that 'Except doesn't do anything'. True,
but is that bad style? I know there are other ways of doing it, but
of all the other "obvious" ones, this appears the most straight
forward.

Should I ignore pylint or is there a more Pythonic way to do this?

If the class of myobj is under your control you could do

class MyObj:
def method(self):
pass

and then later just call

myobj.method()

Result: cleaner client code :)

Peter
 
M

marduk

Based on all the responses received thus far, I thought of a way of
doing it without an exception:

myobj.__dict__.get('method', lambda : None)()

Which is okay if you don't care about the return value of the
method (in my examples I'm assuming .method() just does something
(and returns None). But it's a lot uglier I think than the try/except
block.
 
M

Michael Hudson

marduk said:
Based on all the responses received thus far, I thought of a way of
doing it without an exception:

myobj.__dict__.get('method', lambda : None)()

Uh, I'd say that's pretty unlikely to work. What's wrong with
getattr()?

Cheers,
mwh
 
B

Brandon Craig Rhodes

Michael Hudson said:
try:
meth = myobj.method
except AttributeError:
pass
else:
meth()

I'm confused - why not

meth = getattr(myobj, method)
if meth:
meth()
 
B

Brandon Craig Rhodes

I said:
meth = getattr(myobj, method)
if meth:
meth()

but in fact intended the first line to be

meth = getattr(myobj, method, None)

Sorry for any confusion. :)
 
B

Brandon Craig Rhodes

Brandon Craig Rhodes said:
...but in fact intended the first line to be
meth = getattr(myobj, method, None)

.... where `method' holds the method name, of course. <sigh>
 
I

Istvan Albert

marduk said:
try:
# call optional method
myobj.method()
except AttributeError:
# no biggie
pass


Occasionally I use pylint, which is a good tool, but in the above
snippet pylint will complain that 'Except doesn't do anything'. True,
but is that bad style?

I personally don't like this, not because of pylint but because
it feels like using the wrong solution for the problem.
You could create a base class that has a method that
does nothing and have all your objects inherit from that.

This solution does properly communicate
that the method is optional. Not to mention that you need
to repeat the whole thing if used again in a different
circumstance. Plus something could go wrong inside
existing methods and you'd never know about it.

Why risk all that?

Istvan.
 
D

Donn Cave

Michael Hudson said:
Well,

try:
meth = myobj.method
except AttributeError:
pass
else:
meth()

is possibly better (your version might hide bugs in the method). It's
a pain to do this all the time, though.

Come to think of it

getattr(myobj, "method", lambda :None)()

also acheives the same thing. Bit inscrutable, though.

Along the same lines,

if hasattr(myobj, 'method'):
myobj.method()

That's not uncommon usage, and has the advantage
of more directly and economically saying what the
try/except block is trying to say.

Donn Cave, (e-mail address removed)
 
A

Alex Martelli

marduk said:
Based on all the responses received thus far, I thought of a way of
doing it without an exception:

myobj.__dict__.get('method', lambda : None)()

Have you TRIED this? most likely, myobj.method is NOT reaching into
myobj.__dict__, but rather into type(myobj). getattr is WAY superior!


Alex
 
M

marduk

I personally don't like this, not because of pylint but because
it feels like using the wrong solution for the problem.
You could create a base class that has a method that
does nothing and have all your objects inherit from that.

This solution does properly communicate
that the method is optional. Not to mention that you need
to repeat the whole thing if used again in a different
circumstance. Plus something could go wrong inside
existing methods and you'd never know about it.

Why risk all that?

This is probably overkill for my current circumstance, but I may consider
it in the future. Besides, the class in question is third-party and I'm
merely trying to call method if it exists (version n) and do nothing if it
doesn't exist (version n-1). Although I could subclass the third-party
class and override method()... but as I said, overkill for me right now as
I'm only using the object/method once.

I really liked the getattr suggestion. Thanks to all who responded.
 
H

Heiko Wundram

Am Donnerstag, 9. September 2004 19:56 schrieb marduk:
myobj.__dict__.get('method', lambda : None)()

This won't work when inheritance is in play. See for yourself:
.... def method(self):
.... return "I was called!"
........ pass
....
So, use getattr, which properly walks the inheritance tree:
'I was called!'

Heiko.
 
A

Andrew Dalke

Michael said:
Come to think of it

getattr(myobj, "method", lambda :None)()

also acheives the same thing. Bit inscrutable, though.

Who needs a lambda?

getattr(myobj, "method", Exception)()

Even works for multiple arguments. Now if only
Exception took kwargs...

Still inscrutable, or at least distracting.

(In other words, don't use this.)

Andrew
(e-mail address removed)
 
N

Nicolas Fleury

marduk said:
I commonly use code like this

try:
# call optional method
myobj.method()
except AttributeError:
# no biggie
pass

The problem with that solution is that some code in method() might raise
an AttributeError exception, and the code is broken. Using hasattr or
getattr is definitely better.

Regards,
Nicolas
 

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,206
Messages
2,571,069
Members
47,675
Latest member
RollandKna

Latest Threads

Top