calling python functions using variables

C

creo

Hi all!

this is a (relatively) newbie question


I am writing a shell in Python and I am facing a problem

The problem is, after taking the input from user, i have to execute the
command which is a python function

i invoke an 'ls' command like this
commands.ls()
where commands.py is a file in the same directory

what i want to do is
commands.VARIABLE()
where VARIABLE holds the name of the function which i want to execute
and depends on what the user has typed


what should i do to achieve that?

any help is appreciated

thank you

-creo


P.S. if you want me to clarify the question, please tell me so
 
P

Peter Otten

creo said:
i invoke an 'ls' command like this
commands.ls()
where commands.py is a file in the same directory

what i want to do is
commands.VARIABLE()
where VARIABLE holds the name of the function which i want to execute
and depends on what the user has typed

You want

getattr(commands, VARIABLE)()

Peter
 
B

Ben Finney

Peter Otten said:
You want

getattr(commands, VARIABLE)()

You'll also need to anticipate the situation where the value bound to
VARIABLE is not the name of an attribute in 'commands'.

Either deal with the resulting NameError exception (EAFP[0]) or test
first whether the attribute exists (LBYL[1]).

[0] Easier to Ask Forgiveness than Permission
[1] Look Before You Leap
 
B

bruno at modulix

Ben said:
You want
getattr(commands, VARIABLE)()

You'll also need to anticipate the situation where the value bound to
VARIABLE is not the name of an attribute in 'commands'.

Either deal with the resulting NameError exception (EAFP[0])

try:
getattr(commands, VARIABLE)()
except NameError:
print >> sys.stderr, "Unknown command", VARIABLE
or test
first whether the attribute exists (LBYL[1]).

command = getattr(commands, VARIABLE, None)
if command is None:
print >> sys.stderr, "Unknown command", VARIABLE
else:
command()

I'd go for the first solution.
 
G

Grant Edwards

Either deal with the resulting NameError exception (EAFP[0])

try:
getattr(commands, VARIABLE)()
except NameError:
print >> sys.stderr, "Unknown command", VARIABLE
or test
first whether the attribute exists (LBYL[1]).

command = getattr(commands, VARIABLE, None)
if command is None:
print >> sys.stderr, "Unknown command", VARIABLE
else:
command()

I'd go for the first solution.

Me too. Assuming the user isn't clueless, the normal case is
where the command exists. Write code for the normal case and
use the exception that occurs for exceptional cases.
 
C

Cameron Laird

Either deal with the resulting NameError exception (EAFP[0])

try:
getattr(commands, VARIABLE)()
except NameError:
print >> sys.stderr, "Unknown command", VARIABLE
or test
first whether the attribute exists (LBYL[1]).

command = getattr(commands, VARIABLE, None)
if command is None:
print >> sys.stderr, "Unknown command", VARIABLE
else:
command()

I'd go for the first solution.

Me too. Assuming the user isn't clueless, the normal case is
where the command exists. Write code for the normal case and
use the exception that occurs for exceptional cases.
.
.
.
Guys, I try--I try *hard*--to accept the BetterToAskForgiveness
gospel, but this situation illustrates the discomfort I consistently
feel: how do I know that the NameError means VARIABLE didn't resolve,
rather than that it did, but that evaluation of commands.VARIABLE()
itself didn't throw a NameError? My usual answer: umm, unless I go
to efforts to prevent it, I *don't* know that didn't happen.
 
F

Fredrik Lundh

Cameron said:
Guys, I try--I try *hard*--to accept the BetterToAskForgiveness
gospel, but this situation illustrates the discomfort I consistently
feel: how do I know that the NameError means VARIABLE didn't resolve,
rather than that it did, but that evaluation of commands.VARIABLE()
itself didn't throw a NameError? My usual answer: umm, unless I go
to efforts to prevent it, I *don't* know that didn't happen.

two notes:

1) getattr() raises an AttributeError if the attribute doesn't exist, not a NameError.

2) as you point out, doing too much inside a single try/except often results in hard-
to-find errors and confusing error messages. the try-except-else pattern comes in
handy in cases like this:

try:
f = getattr(commands, name)
except AttributeError:
print "command", name, "not known"
else:
f()

</F>
 
R

Richie Hindle

[Cameron]
try:
getattr(commands, VARIABLE)()
except NameError:
print >> sys.stderr, "Unknown command", VARIABLE

this situation illustrates the discomfort I consistently
feel: how do I know that the NameError means VARIABLE didn't resolve,
rather than that it did, but that evaluation of commands.VARIABLE()
itself didn't throw a NameError? My usual answer: umm, unless I go
to efforts to prevent it, I *don't* know that didn't happen.

The 'try' block should only include the code that you expect to fail with
the given exception. Try this instead:

(Aside: I think AttributeError is correct here, not NameError.)
 
D

Dennis Lee Bieber

.
.
Guys, I try--I try *hard*--to accept the BetterToAskForgiveness
gospel, but this situation illustrates the discomfort I consistently
feel: how do I know that the NameError means VARIABLE didn't resolve,
rather than that it did, but that evaluation of commands.VARIABLE()

I'd suggest that each of your "valid" commands should contain
whatever error checking is appropriate to it -- and if needed, raise
some custom "command failure" exception after handling the real failure
internally.
--
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/
 
B

Ben Finney

bruno at modulix said:
Ben said:
You'll also need to anticipate the situation where the value bound
to VARIABLE is not the name of an attribute in 'commands'.

Either deal with the resulting NameError exception (EAFP[0])

try:
getattr(commands, VARIABLE)()
except NameError:
print >> sys.stderr, "Unknown command", VARIABLE

No. As another poster points out, that will mistakenly catch NameError
exceptions raised *inside* the function.

When catching exceptions, be sure that your 'try' block is only doing
the minimum of stuff that you want exceptions from, so you know what
they mean when they occur.

try:
this_command = getattr(commands, VARIABLE)
except NameError:
print >> sys.stderr, "Unknown command '%s'" % VARIABLE
this_command()
or test first whether the attribute exists (LBYL[1]).

command = getattr(commands, VARIABLE, None)
if command is None:
print >> sys.stderr, "Unknown command", VARIABLE
else:
command()

I'd go for the first solution.

With the caveats mentioned above, yes, I agree.
 
B

Ben Finney

Fredrik Lundh said:
two notes:

1) getattr() raises an AttributeError if the attribute doesn't
exist, not a NameError.

2) as you point out, doing too much inside a single try/except often
results in hard- to-find errors and confusing error messages. the
try-except-else pattern comes in handy in cases like this:

try:
f = getattr(commands, name)
except AttributeError:
print "command", name, "not known"
else:
f()

Gah. As is often the case, Frederick has avoided my mistakes and said
what I wanted to say, better.
 
C

Carl Banks

Fredrik said:
two notes:

1) getattr() raises an AttributeError if the attribute doesn't exist, not a NameError.

2) as you point out, doing too much inside a single try/except often results in hard-
to-find errors and confusing error messages. the try-except-else pattern comes in
handy in cases like this:

try:
f = getattr(commands, name)
except AttributeError:
print "command", name, "not known"
else:
f()

What if commands were an instance of this class:

class CommandClass:
....
def __getattr__(self,attr):
try:
return self.dircontenst[attr]
except KeyError:
raise AttributeError

The call to getattr manages to raise AttributeError even though the
command is known. Yes, self.dircontents[attr] does exist and is valid
in this example, but it still raises AttributeError because dircontents
is spelled wrong.

I make this silly example to point out that Python's dynamicism is a
possible pitfall with ETAFTP even if you're careful. It's something
worth keeping in mind.

Another example, much more realistic: GvR says don't use callable(),
just try calling it and catch CallableError (or whatever it is). Of
course, that error can be raised inside the function; and in this case,
there's no way to isolate only the part you you're checking for an
exception.


Carl Banks
 
C

Carl Banks

Dennis said:
.

I'd suggest that each of your "valid" commands should contain
whatever error checking is appropriate to it -- and if needed, raise
some custom "command failure" exception after handling the real failure
internally.

That probably doesn't help when the exception is due to a bug and not
bad input. If you have an AttributeError due to a bug, it would be
wrong to raise a custom command failure exception.

Carl Banks
 

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
474,298
Messages
2,571,539
Members
48,274
Latest member
HowardKipp

Latest Threads

Top