variables exist

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

    #1

    variables exist

    how testing if a variable exists in python as isset in php??

    thanks
  • Fredrik Lundh

    #2
    Re: variables exist

    "fabian" wrote:
    [color=blue]
    > how testing if a variable exists in python as isset in php??[/color]

    try:
    variable
    except NameError:
    print "variable not set"

    but that is really lousy Python; better make sure you always assign to
    all variables, and use None (or another suitable value) to mark that some
    variable has no meaningful content right now.

    that is, instead of

    if condition:
    variable = 1

    ...

    try:
    variable
    except NameError:
    ....

    write

    variable = None

    if condition:
    variable = 1

    ...

    if variable is None:
    print "variable not set"

    </F>



    Comment

    • Gerald Klix

      #3
      Re: variables exist

      try:
      myVariable
      except NameError:
      print "Not bound"
      else:
      print "Bound"

      If you want to distinguish between the local an the global environment:

      if globals().has_k ey( "myVariable " ):
      ...

      versus

      if locals().has_ke y( ".....


      HTH,
      Gerald

      fabian schrieb:[color=blue]
      > how testing if a variable exists in python as isset in php??
      >
      > thanks[/color]

      --
      GPG-Key: http://keyserver.veridis.com:11371/search?q=0xA140D634

      Comment

      • Brian van den Broek

        #4
        Re: variables exist

        Fredrik Lundh said unto the world upon 2005-04-11 10:14:[color=blue]
        > "fabian" wrote:
        >[color=green]
        >>how testing if a variable exists in python as isset in php??[/color]
        >
        >
        > try:
        > variable
        > except NameError:
        > print "variable not set"
        >
        > but that is really lousy Python; better make sure you always assign to
        > all variables, and use None (or another suitable value) to mark that some
        > variable has no meaningful content right now.
        >
        > that is, instead of[/color]

        <SNIP full try/except example>
        [color=blue]
        > write
        >
        > variable = None
        >
        > if condition:
        > variable = 1
        >
        > ...
        >
        > if variable is None:
        > print "variable not set"
        >
        > </F>[/color]


        Hi Fredrik and all,

        I'm a hobbyist and still learning, but the claim the try/except is
        "lousy Python" surprise me a bit. The try/except way seems like an
        instance of "Easier to ask Forgiveness than Permission", and my sense
        is that in 95% of cases that approach is widely considered more
        Pythonic than LBYL (of which the suggested idiom seems reminiscent).

        As it happens, most of my code does preset names to None, but reading
        this thread made me wonder. Are you suggesting setting to None is
        better as it makes explicit that there is nothing there, but this may
        change in the future? (This is why I do it.) Or for some other reason?

        I have no partisan interests either way; I'm just trying to
        understand. Thanks and best,

        Brian vdB


        Comment

        • Steven Bethard

          #5
          Re: variables exist

          Brian van den Broek wrote:[color=blue]
          > Fredrik Lundh said unto the world upon 2005-04-11 10:14:[color=green]
          >> "fabian" wrote:[color=darkred]
          >>> how testing if a variable exists in python as isset in php??[/color]
          >>
          >> try:
          >> variable
          >> except NameError:
          >> print "variable not set"
          >>
          >> but that is really lousy Python; better make sure you always assign to
          >> all variables, and use None (or another suitable value) to mark that some
          >> variable has no meaningful content right now.
          >>
          >> that is, instead of[/color]
          > <SNIP full try/except example>[color=green]
          >> write
          >>
          >> variable = None
          >> if condition:
          >> variable = 1
          >> ...
          >> if variable is None:
          >> print "variable not set"[/color]
          >
          > I'm a hobbyist and still learning, but the claim the try/except is
          > "lousy Python" surprise me a bit. The try/except way seems like an
          > instance of "Easier to ask Forgiveness than Permission", and my sense
          > is that in 95% of cases that approach is widely considered more Pythonic
          > than LBYL (of which the suggested idiom seems reminiscent).
          >
          > As it happens, most of my code does preset names to None, but reading
          > this thread made me wonder. Are you suggesting setting to None is
          > better as it makes explicit that there is nothing there, but this may
          > change in the future? (This is why I do it.) Or for some other reason?[/color]

          I had a similar reaction to Fredrik's statement. In general, I wouldn't
          call a try/except solution lousy style, as long as the path through
          except was sufficiently "exceptiona l". That is, for code like:

          if condition_that_ happens_99_perc ent_of_the_time :
          variable = 1
          try:
          variable
          except NameError:
          print "variable not set"

          seems perfectly reasonable to me, because the exception is caught in the
          *exceptional* case. However, if one case isn't clearly the exceptional
          one, then it probably doesn't makes sense to use an exception, and I'd
          write it like:

          variable = None
          if condition_that_ happens_40_perc ent_of_the_time :
          variable = 1
          ...
          if variable is None:
          print "variable not set"

          Actually, I typically refactor my code so that I can write situations
          like this as:

          if condition_that_ happens_40_perc ent_of_the_time :
          variable = 1
          ...
          else:
          print "variable not set"

          But the point still stands. If the variable being unset really is an
          exceptional case, use an exception. If it's not, then an if/else block
          is probably the better way to go.

          STeVe

          Comment

          • Richard Brodie

            #6
            Re: variables exist


            "Brian van den Broek" <bvande@po-box.mcgill.ca> wrote in message
            news:mailman.17 03.1113237192.1 799.python-list@python.org ...
            [color=blue]
            > I'm a hobbyist and still learning, but the claim the try/except is
            > "lousy Python" surprise me a bit.[/color]

            I think it wasn't the use of try/except as such. It's more that
            if you're the developer you ought to know whether variables
            are defined or not. It might be a sign you're using global
            variables more often than would be considered good style in
            Python.


            Comment

            • Brian van den Broek

              #7
              Re: variables exist

              Richard Brodie said unto the world upon 2005-04-12 04:56:[color=blue]
              > "Brian van den Broek" <bvande@po-box.mcgill.ca> wrote in message
              > news:mailman.17 03.1113237192.1 799.python-list@python.org ...
              >
              >[color=green]
              >>I'm a hobbyist and still learning, but the claim the try/except is
              >>"lousy Python" surprise me a bit.[/color]
              >
              >
              > I think it wasn't the use of try/except as such. It's more that
              > if you're the developer you ought to know whether variables
              > are defined or not. It might be a sign you're using global
              > variables more often than would be considered good style in
              > Python.[/color]

              Richard and STeVe,

              thanks for the replies :-)

              I see your point, Richard. Though where it has come up for me most
              often is code internal to a class, where I only need a "real" value
              for a class attribute in some cases, depending upon the inputs to the
              class __init__. "Globals are bad" is one lesson I have learned :-)

              STeVe stressed that the try/except solution is only really appropriate
              for cases where the failure to have the variable defined is quite
              rare. Even though wary of "the root of all evil ... " that seems a
              good reminder. Thanks.

              Best to all,

              Brian vdB

              Comment

              • Scott David Daniels

                #8
                Re: variables exist

                Brian van den Broek wrote:[color=blue]
                >... STeVe stressed that the try/except solution is only really appropriate
                > for cases where the failure to have the variable defined is quite rare.[/color]

                Beware: C++ and Java have an immense overhead for exceptions. Python
                has a very lightweight exception mechanism. You should _very_seldom_
                choose exceptions or not on the basis of performance without measuring
                the actual use; you are sure to be surprised.

                Structure your code to be easiest to understand. _If_ it is too slow,
                investigate ways to improve its performance. The usual way is to
                build better data structures and use better algorithms. Only in the
                core of a frequently used inner loop should you even care about the
                cost of exceptions. Even then, you can often lift the exception
                handler around the loop and recover the most necessary performance.

                --Scott David Daniels
                Scott.Daniels@A cm.Org

                Comment

                • Fredrik Lundh

                  #9
                  Re: variables exist

                  Scott David Daniels wrote:[color=blue][color=green]
                  > >... STeVe stressed that the try/except solution is only really[/color][/color]
                  appropriate
                  [color=blue][color=green]
                  > > for cases where the failure to have the variable defined is quite rare.[/color]
                  >
                  > Beware: C++ and Java have an immense overhead for exceptions. Python
                  > has a very lightweight exception mechanism. You should _very_seldom_
                  > choose exceptions or not on the basis of performance without measuring
                  > the actual use; you are sure to be surprised.
                  >
                  > Structure your code to be easiest to understand. _If_ it is too slow,
                  > investigate ways to improve its performance. The usual way is to
                  > build better data structures and use better algorithms. Only in the
                  > core of a frequently used inner loop should you even care about the
                  > cost of exceptions.[/color]

                  you haven't really read this thread, have you?

                  </F>



                  Comment

                  • Steven Bethard

                    #10
                    Re: variables exist

                    Scott David Daniels wrote:[color=blue]
                    > Brian van den Broek wrote:
                    >[color=green]
                    >> ... STeVe stressed that the try/except solution is only really
                    >> appropriate for cases where the failure to have the variable defined
                    >> is quite rare.[/color]
                    >
                    > Beware: C++ and Java have an immense overhead for exceptions. Python
                    > has a very lightweight exception mechanism. You should _very_seldom_
                    > choose exceptions or not on the basis of performance without measuring
                    > the actual use; you are sure to be surprised.[/color]

                    I'll just point out that I wasn't suggesting that try/except should be
                    used as an optimization, but that it should be used when *exceptional*
                    behavior is encountered. Using try/except for non-exceptional behavior
                    can be confusing for readers of your code who assume the normal
                    semantics. Just to make sure my point is clear, a great case for
                    try/except is with dictionaries, e.g.
                    try:
                    v = d[k]
                    except KeyError:
                    ...
                    In this case, the key not being in the dictionary clearly makes sense as
                    exceptional behavior because there's no reason to have a dictionary if
                    there's nothing in it. Similarly, try/excepts are great for dealing
                    with duck typing issues, e.g.:
                    def f(mapping)
                    try:
                    itervalues = mapping.iterval ues
                    except AttributeError:
                    values = (mapping[k] for k in mapping)
                    else:
                    values = itervalues()
                    ...
                    Again, the point is that the AttributeError is the *exceptional*
                    behavior; f expects a mapping with an itervalues method, and if it
                    receives an object that doesn't have one, it has to deal with the
                    exceptional case of replacing that method.

                    Anyway, I hope that clarifies my intentions. Use try/except when it
                    makes sense to talk about something as being *exceptional* behavior. If
                    it doesn't, you should probably use if/else.

                    STeVe

                    P.S. That said, there *are* performance differences. Here's a test that
                    shows how try/except can be more costly the more often the except clause
                    is reached:

                    ----------------------------------------------------------------------
                    import timeit

                    def ifelse(mapping, key):
                    if key in mapping:
                    return mapping[key]
                    else:
                    return None

                    def tryexcept(mappi ng, key):
                    try:
                    return mapping[key]
                    except KeyError:
                    return None

                    setup_code = """\
                    from __main__ import %s as func
                    mapping = %s
                    keys = %s
                    """

                    test_code = '[func(mapping, key) for key in keys]'

                    def get_time(func, mapping, keys):
                    return timeit.Timer(te st_code, setup_code % (
                    func.__name__, mapping, keys)).timeit(1 000)

                    if __name__ == '__main__':
                    N = 1000
                    mapping = dict((i, i**2) for i in xrange(N))
                    for i in [0, 1, 2, 4, 8]:
                    number_missing = i*N/100
                    keys = range(number_mi ssing, N + number_missing)
                    ifelse_time, tryexcept_time = (get_time(func, mapping, keys)
                    for func in [ifelse, tryexcept])
                    result = ['%3i%%' % (100*number_mis sing/N)]
                    for time, func in sorted([(ifelse_time, ifelse),
                    (tryexcept_time , tryexcept)]):
                    result.extend(['%.4f' % time, '%10s' % func.__name__])
                    print '\t'.join(resul t)
                    ----------------------------------------------------------------------

                    And the results I get from running it:

                    [D:\Steve]$ test.py
                    0% 0.8467 tryexcept 0.9415 ifelse
                    1% 0.9374 tryexcept 0.9430 ifelse
                    2% 0.9499 ifelse 1.0375 tryexcept
                    4% 0.9580 ifelse 1.1576 tryexcept
                    8% 0.9333 ifelse 1.4187 tryexcept

                    Thus try/except is better when almost all of the keys can be found in
                    the dict, but as soon as even 2% of the keys cannot, if/else is the more
                    efficient solution. This is toy data, so obviously YMMV. But if you
                    use try/except for a very frequent occurrence instead of an exceptional
                    one, you may notice a performance hit.

                    Comment

                    • Michael J. Fromberger

                      #11
                      Re: variables exist

                      In article <9622d535.05041 10552.1e070e8d@ posting.google. com>,
                      fabian.steels@f ree.fr (fabian) wrote:
                      [color=blue]
                      > how testing if a variable exists in python as isset in php??
                      >[/color]

                      Would the following be a satisfactory implementation?

                      def isset(varname, lloc = locals()):
                      return varname in lloc or varname in globals()

                      I believe this works as desired:
                      [color=blue][color=green][color=darkred]
                      >>> x = 5
                      >>> def f(y):[/color][/color][/color]
                      ... z = 10
                      ... print isset('z') ## ==> True
                      ... print isset('y') ## ==> True
                      ... print isset('x') ## ==> True
                      ...

                      Tests:[color=blue][color=green][color=darkred]
                      >>> f(1) ## As shown above
                      >>> print isset('z') ## ==> False
                      >>> print isset('y') ## ==> False
                      >>> print isset('x') ## ==> True
                      >>> print isset('varname' ) ## ==> False
                      >>> print isset('lloc') ## ==> False
                      >>> lloc = "foo!"
                      >>> print isset('lloc') ## ==> True[/color][/color][/color]

                      Perhaps this is not the most elegant solution, but I believe it handles
                      scoping correctly.

                      -M

                      --
                      Michael J. Fromberger | Lecturer, Dept. of Computer Science
                      http://www.dartmouth.edu/~sting/ | Dartmouth College, Hanover, NH, USA

                      Comment

                      • Peter Otten

                        #12
                        Re: variables exist

                        Michael J. Fromberger wrote:
                        [color=blue]
                        > Would the following be a satisfactory implementation?
                        >
                        > def isset(varname, lloc = locals()):
                        > return varname in lloc or varname in globals()
                        >
                        > I believe this works as desired:
                        >[color=green][color=darkred]
                        > >>> x = 5
                        > >>> def f(y):[/color][/color]
                        > ... z = 10
                        > ... print isset('z') ## ==> True
                        > ... print isset('y') ## ==> True
                        > ... print isset('x') ## ==> True
                        > ...
                        >
                        > Tests:[color=green][color=darkred]
                        > >>> f(1) ## As shown above[/color][/color][/color]

                        No, try it again in a fresh interpreter:
                        [color=blue][color=green][color=darkred]
                        >>> def isset(name, loc=locals()):[/color][/color][/color]
                        .... return name in loc or name in globals()
                        ....[color=blue][color=green][color=darkred]
                        >>> x = 5
                        >>> def f(y):[/color][/color][/color]
                        .... z = 10
                        .... print isset("x"), isset("y"), isset("z")
                        ....[color=blue][color=green][color=darkred]
                        >>> f(42)[/color][/color][/color]
                        True False False[color=blue][color=green][color=darkred]
                        >>>[/color][/color][/color]

                        It may seem from the above that at least the global variable "x" is found
                        correctly, but beware, the global namespace where isset() is defined is
                        searched, not the one where it is called. Untested:

                        def isset(name):
                        frame = sys._getframe(1 )
                        return name in frame.f_locals or name in frame.f_globals

                        might work, but is too magic for my taste.

                        Peter

                        Comment

                        Working...