calling a function from string

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

    calling a function from string

    hi,

    i have a function that I could like to call, but to make it more
    dynamic I am constructing a string first that could equivalent to the
    name of the function I wish to call. how could I do that? the string
    could might include name of the module.

    for example

    a_string = 'datetime.' + 'today()'

    how could I call a_string as function?

    Thanks
    james

  • Francesco Guerrieri

    #2
    Re: calling a function from string

    On 10/22/07, james_027 <cai.haibin@gma il.comwrote:
    hi,
    >
    i have a function that I could like to call, but to make it more
    dynamic I am constructing a string first that could equivalent to the
    name of the function I wish to call. how could I do that? the string
    could might include name of the module.
    >
    for example
    >
    a_string = 'datetime.' + 'today()'
    >
    how could I call a_string as function?
    you could use getattr:

    function_name = 'time' # this is a string
    module_name = 'time' # this is a string, too

    my_function = getattr(module_ name, function_name) # this is the
    function object,
    # equivalent to my_function = time.time
    my_function() # This is the function call, equivalent to time.time()

    bye
    francesco

    Comment

    • Trent Nelson

      #3
      RE: calling a function from string

      i have a function that I could like to call, but to make it more
      dynamic I am constructing a string first that could equivalent to the
      name of the function I wish to call. how could I do that? the string
      could might include name of the module.

      for example

      a_string = 'datetime.' + 'today()'

      how could I call a_string as function?
      Use 'eval' in one of the following fashions:

      a_string_1 = 'datetime.' + 'today'
      a_string_2 = 'datetime.' + 'today()'

      eval(a_string_1 )()
      eval(a_string_2 )


      Trent.

      Comment

      • Jarek Zgoda

        #4
        Re: calling a function from string

        Trent Nelson napisa³(a):
        >i have a function that I could like to call, but to make it more
        >dynamic I am constructing a string first that could equivalent to the
        >name of the function I wish to call. how could I do that? the string
        >could might include name of the module.
        >>
        >for example
        >>
        >a_string = 'datetime.' + 'today()'
        >>
        >how could I call a_string as function?
        >
        Use 'eval' in one of the following fashions:
        >
        a_string_1 = 'datetime.' + 'today'
        a_string_2 = 'datetime.' + 'today()'
        >
        eval(a_string_1 )()
        eval(a_string_2 )
        Do not use eval(). Not only it's deprecated, it's also unsafe.

        --
        Jarek Zgoda
        Skype: jzgoda | GTalk: zgoda@jabber.as ter.pl | voice: +48228430101

        "We read Knuth so you don't have to." (Tim Peters)

        Comment

        • Dustan

          #5
          Re: calling a function from string

          On Oct 22, 4:41 am, "Francesco Guerrieri" <f.guerri...@gm ail.com>
          wrote:
          On 10/22/07, james_027 <cai.hai...@gma il.comwrote:
          >
          hi,
          >
          i have a function that I could like to call, but to make it more
          dynamic I am constructing a string first that could equivalent to the
          name of the function I wish to call. how could I do that? the string
          could might include name of the module.
          >
          for example
          >
          a_string = 'datetime.' + 'today()'
          >
          how could I call a_string as function?
          >
          you could use getattr:
          >
          function_name = 'time' # this is a string
          module_name = 'time' # this is a string, too
          >
          my_function = getattr(module_ name, function_name) # this is the
          function object,
          # equivalent to my_function = time.time

          Not quite.

          =============== =============== ==============
          >>function_na me = 'time' # this is a string
          >>module_name = 'time' # this is a string, too
          >>my_function = getattr(module_ name, function_name)
          Traceback (most recent call last):
          File "<pyshell#3 >", line 1, in <module>
          my_function = getattr(module_ name, function_name)
          AttributeError: 'str' object has no attribute 'time'
          =============== =============== ==============

          It's actually equivalent to:

          =============== =============== ==============
          >>"time".time
          Traceback (most recent call last):
          File "<pyshell#0 >", line 1, in <module>
          "time".time
          AttributeError: 'str' object has no attribute 'time'
          =============== =============== ==============

          Comment

          • Dustan

            #6
            Re: calling a function from string

            On Oct 22, 5:46 am, Jarek Zgoda <jzg...@o2.usun .plwrote:
            Do not use eval(). Not only it's deprecated, it's also unsafe.
            I don't think it's deprecated; it doesn't say so:


            Comment

            • Bruno Desthuilliers

              #7
              Re: calling a function from string

              james_027 a écrit :
              hi,
              >
              i have a function that I could like to call, but to make it more
              dynamic I am constructing a string first that could equivalent to the
              name of the function I wish to call. how could I do that? the string
              could might include name of the module.
              >
              for example
              >
              a_string = 'datetime.' + 'today()'
              >
              how could I call a_string as function?
              The obvious answer is to use eval or exec, but it's 99.99 times out of
              100 the wrong solution.

              Better solutions usually rely on Python's introspection features -
              mostly globals(), locals(), sys.modules, and of course getattr().

              Comment

              • Bruno Desthuilliers

                #8
                Re: calling a function from string

                Jarek Zgoda a écrit :
                Trent Nelson napisa³(a):
                >>i have a function that I could like to call, but to make it more
                >>dynamic I am constructing a string first that could equivalent to the
                >>name of the function I wish to call. how could I do that? the string
                >>could might include name of the module.
                >>>
                >>for example
                >>>
                >>a_string = 'datetime.' + 'today()'
                >>>
                >>how could I call a_string as function?
                >Use 'eval' in one of the following fashions:
                >>
                >a_string_1 = 'datetime.' + 'today'
                >a_string_2 = 'datetime.' + 'today()'
                >>
                >eval(a_string_ 1)()
                >eval(a_string_ 2)
                >
                Do not use eval(). Not only it's deprecated,
                Chapter and verse ???
                it's also unsafe.
                it's *potentially* unsafe. As long as the eval'd code comes from a
                trusted source, there should be no security problem.

                I agree that eval is usually not the solution, but mainly because Python
                has far better (wrt/ readability and maintainance) options for this kind
                of things.

                Comment

                • Shane Geiger

                  #9
                  Re: calling a function from string

                  >>exec("impor t datetime") ; exec("x = datetime." + "date." + "today()")
                  >>print x
                  2007-10-22




                  james_027 wrote:
                  hi,
                  >
                  i have a function that I could like to call, but to make it more
                  dynamic I am constructing a string first that could equivalent to the
                  name of the function I wish to call. how could I do that? the string
                  could might include name of the module.
                  >
                  for example
                  >
                  a_string = 'datetime.' + 'today()'
                  >
                  how could I call a_string as function?
                  >
                  Thanks
                  james
                  >
                  >

                  --
                  Shane Geiger
                  IT Director
                  National Council on Economic Education
                  sgeiger@ncee.ne t | 402-438-8958 | http://www.ncee.net

                  Leading the Campaign for Economic and Financial Literacy


                  Comment

                  • Steven D'Aprano

                    #10
                    Re: calling a function from string

                    On Mon, 22 Oct 2007 08:54:02 +0000, james_027 wrote:
                    hi,
                    >
                    i have a function that I could like to call, but to make it more dynamic
                    I am constructing a string first that could equivalent to the name of
                    the function I wish to call.
                    That is not the right solution to dynamic functions. There is a much
                    better way.

                    how could I do that? the string could might
                    include name of the module.
                    >
                    for example
                    >
                    a_string = 'datetime.' + 'today()'
                    >
                    how could I call a_string as function?
                    Others have suggested eval() and exec. Both will work, but have MAJOR
                    security implications.

                    The right way to work with "dynamic functions" is to remember that Python
                    treats functions as first-class objects just like strings and ints and
                    lists. Here's a simple example:

                    Suppose I have a function that takes a string and converts it to another
                    object type.

                    def converter(x, convert_to):
                    if convert_to == 'int':
                    return int(x)
                    elif convert_to == 'float':
                    return float(x)
                    elif convert_to == 'list':
                    return list(x)
                    else:
                    raise ValueError("don 't know that type")

                    and then use the function like this:

                    my_float = converter('12.3 45', 'float')


                    That's the wrong way to do it. This is the right way:

                    def converter(x, convert_to):
                    return convert_to(x)

                    my_float = converter('12.3 45', float)

                    See the subtle difference?

                    'float' is a string, and it has no special meaning.

                    float() with brackets says "call the function float".

                    float without brackets *is* the function float. You can pass it around
                    like any other object (strings, lists, ints, etc.) and call it later.

                    Try this example:

                    import datetime, time
                    functions = [int, float, datetime.time, time.time]
                    for f in functions:
                    print f()



                    --
                    Steven

                    Comment

                    • Steven D'Aprano

                      #11
                      Re: calling a function from string

                      On Mon, 22 Oct 2007 23:16:38 +0000, Steven D'Aprano wrote:
                      >how could I call a_string as function?
                      >
                      Others have suggested eval() and exec. Both will work, but have MAJOR
                      security implications.
                      Oh, and they are seriously slower too.
                      >>import timeit
                      >>timeit.Timer( 'f("2.3")',
                      .... 'f = float').repeat( ) # time using 1st class function
                      [1.7266130447387 695, 0.9764540195465 0879, 0.9727139472961 4258]
                      >>timeit.Timer( 'eval("float")( "2.3")'
                      .... ).repeat() # time using eval and a string
                      [20.628923177719 116, 19.704520940780 64, 19.783280849456 787]


                      --
                      Steven.

                      Comment

                      Working...