calling python functions using variables

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • creo

    #1

    calling python functions using variables

    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.VARIAB LE()
    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

  • Peter Otten

    #2
    Re: calling python functions using variables

    creo wrote:
    [color=blue]
    > 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.VARIAB LE()
    > where VARIABLE holds the name of the function which i want to execute
    > and depends on what the user has typed[/color]

    You want

    getattr(command s, VARIABLE)()

    Peter

    Comment

    • Ben Finney

      #3
      Re: calling python functions using variables

      Peter Otten <__peter__@web. de> writes:
      [color=blue]
      > creo wrote:[color=green]
      > > what i want to do is
      > > commands.VARIAB LE()
      > > where VARIABLE holds the name of the function which i want to execute
      > > and depends on what the user has typed[/color]
      >
      > You want
      >
      > getattr(command s, VARIABLE)()[/color]

      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

      --
      \ "Our products just aren't engineered for security." -- Brian |
      `\ Valentine, senior vice-president of Microsoft Windows |
      _o__) development |
      Ben Finney

      Comment

      • bruno at modulix

        #4
        Re: calling python functions using variables

        Ben Finney wrote:[color=blue]
        > Peter Otten <__peter__@web. de> writes:[/color]
        (snip)[color=blue][color=green]
        >>
        >>You want
        >>getattr(comma nds, VARIABLE)()[/color]
        >
        > 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])[/color]

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

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

        I'd go for the first solution.

        --
        bruno desthuilliers
        python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
        p in 'onurb@xiludom. gro'.split('@')])"

        Comment

        • Grant Edwards

          #5
          Re: calling python functions using variables

          On 2006-05-19, bruno at modulix <onurb@xiludom. gro> wrote:
          [color=blue][color=green]
          >> Either deal with the resulting NameError exception (EAFP[0])[/color]
          >
          > try:
          > getattr(command s, VARIABLE)()
          > except NameError:
          > print >> sys.stderr, "Unknown command", VARIABLE
          >[color=green]
          >> or test
          >> first whether the attribute exists (LBYL[1]).[/color]
          >
          > command = getattr(command s, VARIABLE, None)
          > if command is None:
          > print >> sys.stderr, "Unknown command", VARIABLE
          > else:
          > command()
          >
          > I'd go for the first solution.[/color]

          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.

          --
          Grant Edwards grante Yow! This PIZZA symbolizes
          at my COMPLETE EMOTIONAL
          visi.com RECOVERY!!

          Comment

          • Cameron Laird

            #6
            Exception style (was: calling python functions using variables)

            In article <126rjus43k450d f@corp.supernew s.com>,
            Grant Edwards <grante@visi.co m> wrote:[color=blue]
            >On 2006-05-19, bruno at modulix <onurb@xiludom. gro> wrote:
            >[color=green][color=darkred]
            >>> Either deal with the resulting NameError exception (EAFP[0])[/color]
            >>
            >> try:
            >> getattr(command s, VARIABLE)()
            >> except NameError:
            >> print >> sys.stderr, "Unknown command", VARIABLE
            >>[color=darkred]
            >>> or test
            >>> first whether the attribute exists (LBYL[1]).[/color]
            >>
            >> command = getattr(command s, VARIABLE, None)
            >> if command is None:
            >> print >> sys.stderr, "Unknown command", VARIABLE
            >> else:
            >> command()
            >>
            >> I'd go for the first solution.[/color]
            >
            >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.[/color]

            Comment

            • Fredrik Lundh

              #7
              Re: Exception style (was: calling python functions using variables)

              Cameron Laird wrote:
              [color=blue]
              > Guys, I try--I try *hard*--to accept the BetterToAskForg iveness
              > 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.VARIAB LE()
              > 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.[/color]

              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(command s, name)
              except AttributeError:
              print "command", name, "not known"
              else:
              f()

              </F>



              Comment

              • Richie Hindle

                #8
                Re: Exception style (was: calling python functions using variables)


                [Cameron][color=blue]
                > try:
                > getattr(command s, 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.VARIAB LE()
                > 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.[/color]

                The 'try' block should only include the code that you expect to fail with
                the given exception. Try this instead:
                [color=blue][color=green][color=darkred]
                >>> try:
                >>> command = getattr(command s, VARIABLE)
                >>> except AttributeError:
                >>> print >> sys.stderr, "Unknown command", VARIABLE
                >>> else:
                >>> command()[/color][/color][/color]

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

                --
                Richie Hindle
                richie@entrian. com

                Comment

                • bruno at modulix

                  #9
                  Re: Exception style

                  Fredrik Lundh wrote:[color=blue]
                  > Cameron Laird wrote:
                  >
                  >[color=green]
                  >>Guys, I try--I try *hard*--to accept the BetterToAskForg iveness
                  >>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.VARIAB LE()
                  >>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.[/color]
                  >
                  >
                  > two notes:
                  >
                  > 1) getattr() raises an AttributeError if the attribute doesn't exist, not a NameError.[/color]

                  oops ! My bad :(


                  --
                  bruno desthuilliers
                  python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
                  p in 'onurb@xiludom. gro'.split('@')])"

                  Comment

                  • Ben Finney

                    #10
                    Re: calling python functions using variables

                    bruno at modulix <onurb@xiludom. gro> writes:
                    [color=blue]
                    > Ben Finney wrote:[color=green]
                    > > 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])[/color]
                    >
                    > try:
                    > getattr(command s, VARIABLE)()
                    > except NameError:
                    > print >> sys.stderr, "Unknown command", VARIABLE[/color]

                    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(command s, VARIABLE)
                    except NameError:
                    print >> sys.stderr, "Unknown command '%s'" % VARIABLE
                    this_command()
                    [color=blue][color=green]
                    > > or test first whether the attribute exists (LBYL[1]).[/color]
                    >
                    > command = getattr(command s, VARIABLE, None)
                    > if command is None:
                    > print >> sys.stderr, "Unknown command", VARIABLE
                    > else:
                    > command()
                    >
                    > I'd go for the first solution.[/color]

                    With the caveats mentioned above, yes, I agree.

                    --
                    \ "I was arrested today for scalping low numbers at the deli. |
                    `\ Sold a number 3 for 28 bucks." -- Steven Wright |
                    _o__) |
                    Ben Finney

                    Comment

                    • Ben Finney

                      #11
                      Re: Exception style

                      "Fredrik Lundh" <fredrik@python ware.com> writes:
                      [color=blue]
                      > Cameron Laird wrote:[color=green]
                      > > how do I know that the NameError means VARIABLE didn't resolve,
                      > > rather than that it did, but that evaluation of
                      > > commands.VARIAB LE() 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.[/color]
                      >
                      > 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(command s, name)
                      > except AttributeError:
                      > print "command", name, "not known"
                      > else:
                      > f()[/color]

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

                      --
                      \ "There are only two ways to live your life. One is as though |
                      `\ nothing is a miracle. The other is as if everything is." -- |
                      _o__) Albert Einstein |
                      Ben Finney

                      Comment

                      • Carl Banks

                        #12
                        Re: Exception style (was: calling python functions using variables)

                        Fredrik Lundh wrote:[color=blue]
                        > Cameron Laird wrote:
                        >[color=green]
                        > > Guys, I try--I try *hard*--to accept the BetterToAskForg iveness
                        > > 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.VARIAB LE()
                        > > 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.[/color]
                        >
                        > 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(command s, name)
                        > except AttributeError:
                        > print "command", name, "not known"
                        > else:
                        > f()[/color]

                        What if commands were an instance of this class:

                        class CommandClass:
                        ....
                        def __getattr__(sel f,attr):
                        try:
                        return self.dircontens t[attr]
                        except KeyError:
                        raise AttributeError

                        The call to getattr manages to raise AttributeError even though the
                        command is known. Yes, self.dircontent s[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

                        Comment

                        • Carl Banks

                          #13
                          Re: Exception style (was: calling python functions using variables)

                          Dennis Lee Bieber wrote:[color=blue]
                          > On Fri, 19 May 2006 14:41:13 +0000, claird@lairds.u s (Cameron Laird)
                          > declaimed the following in comp.lang.pytho n: .[color=green]
                          > > Guys, I try--I try *hard*--to accept the BetterToAskForg iveness
                          > > 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.VARIAB LE()[/color]
                          >
                          > 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.[/color]

                          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

                          Comment

                          Working...