Static variables

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

    #1

    Static variables

    Hello,
    does python have static variables? I mean function-local variables that keep
    their state between invocations of the function.

    Thanks,

    Florian
  • Neil Cerutti

    #2
    Re: Static variables

    On 2007-01-24, Florian Lindner <Florian.Lindne r@xgm.dewrote:
    does python have static variables? I mean function-local
    variables that keep their state between invocations of the
    function.
    Yup. Here's a nice way. I don't how recent your Python must be
    to support this, though.
    >>def foo(x):
    .... print foo.static_n, x
    .... foo.static_n += 1
    ....
    >>foo.static_ n = 0
    >>for i in range(5):
    .... foo("?")
    ....
    0 ?
    1 ?
    2 ?
    3 ?
    4 ?

    If you need to use an earlier version, then a "boxed" value
    stored as a keyword parameter will also work.
    >>def foo(x, s=[0]):
    .... print s[0], x
    .... s[0] += 1
    ....
    >>for i in range(5):
    .... foo("!")
    ....
    0 !
    1 !
    2 !
    3 !
    4 !

    The latter is not as nice, since your "static" variable is easy
    to clobber by passing something into the function.

    --
    Neil Cerutti

    Comment

    • Bruno Desthuilliers

      #3
      Re: Static variables

      Florian Lindner a écrit :
      Hello,
      does python have static variables? I mean function-local variables that keep
      their state between invocations of the function.
      Not directly. But there are ways to have similar behaviour:

      1/ the mutable default argument hack:

      def fun(arg, _hidden_state=[0]):
      _hidden_state[0] += arg
      return _hidden_static[0] * 2

      2/ using OO:

      class Fun(object):
      def __init__(self, static=0):
      self._state = static
      def __call__(self, arg):
      self._state += arg
      return self._state * 2

      fun = Fun()


      HTH

      Comment

      • Bruno Desthuilliers

        #4
        Re: Static variables

        Neil Cerutti a écrit :
        On 2007-01-24, Florian Lindner <Florian.Lindne r@xgm.dewrote:
        >
        >>does python have static variables? I mean function-local
        >>variables that keep their state between invocations of the
        >>function.
        >
        >
        Yup. Here's a nice way. I don't how recent your Python must be
        to support this, though.
        >
        >
        >>>>def foo(x):
        >
        ... print foo.static_n, x
        ... foo.static_n += 1
        ...
        >
        >>>>foo.static_ n = 0
        Yup,I had forgotten this one. FWIW, it's an old trick.

        There's also the closure solution:

        def make_foo(start_ at=0):
        static = [start_at]
        def foo(x):
        print static[0], x
        static[0] += 1
        return foo

        foo = make_foo()

        And this let you share state between functions:

        def make_counter(st art_at=0, step=1):
        count = [start_at]
        def inc():
        count[0] += step
        return count[0]
        def reset():
        count[0] = [start_at]
        return count[0]
        def peek():
        return count[0]

        return inc, reset, peek

        foo, bar, baaz = make_counter(42 , -1)
        print baaz()
        for x in range(5):
        print foo()
        print bar()
        print baaz()

        Comment

        • Steven D'Aprano

          #5
          Re: Static variables

          On Wed, 24 Jan 2007 21:48:38 +0100, Florian Lindner wrote:
          Hello,
          does python have static variables? I mean function-local variables that keep
          their state between invocations of the function.
          There are two ways of doing that (that I know of).

          The simplest method is by having a mutable default argument. Here's an
          example:

          def foo(x, _history=[]):
          print _history, x
          _history.append (x)
          >>foo(2)
          [] 2
          >>foo(3)
          [2] 3
          >>foo(5)
          [2, 3] 5


          Another method is to add an attribute to the function after you've created
          it:

          def foo(x):
          print foo.last, x
          foo.last = x

          foo.last = None

          >>foo(3)
          None 3
          >>foo(6)
          3 6
          >>foo(2)
          6 2


          But the most powerful method is using generators, which remember their
          entire internal state between calls. Here's a simple example, one that
          returns the integers 0, 1, 3, 6, 10, ...

          def number_series() :
          increment = 1
          n = 0
          while True:
          yield n # instead of return
          n += increment
          increment += 1


          Notice that in this case there is no exit to the function: it loops
          forever because the series goes on for ever. If you want to exit the
          generator, just use a plain return statement (don't return anything), or
          just exit the loop and fall off the end of the function.

          This is how we might use it:

          Create an iterator object from the generator function, and print the first
          six values:
          >>gen = number_series()
          >>for i in range(6): print gen.next()
          ....
          0
          1
          3
          6
          10
          15

          Sum the values from the current point up to 100:
          >>s = 0
          >>n = gen.next()
          >>n
          21
          >>for x in gen:
          .... if x >= 100:
          .... break
          .... n += x
          ....
          >>n
          420

          Reset the iterator to the start:
          >>gen = number_series()
          For generators that terminate, you can get all the values in one go with
          this:

          everything = list(gen) # or everything = list(number_ser ies())

          but don't try this on my example, because it doesn't terminate!


          --
          Steven.

          Comment

          • Gary Herron

            #6
            Re: Static variables

            Florian Lindner wrote:
            Hello,
            does python have static variables? I mean function-local variables that keep
            their state between invocations of the function.
            >
            Thanks,
            >
            Florian
            >
            Nope. Not really.

            In new versions of Python, functions and methods can have attributes
            that can be used like function level static variables.

            However, I usually use module level attributes for such things.

            Gary Herron

            Comment

            • Gary Herron

              #7
              Re: Static variables

              Florian Lindner wrote:
              Hello,
              does python have static variables? I mean function-local variables that keep
              their state between invocations of the function.
              >
              Thanks,
              >
              Florian
              >
              Nope. Not really.

              In new versions of Python, functions and methods can have attributes
              that can be used like function level static variables.

              However, I usually use module level attributes for such things.

              Gary Herron

              Comment

              • bearophileHUGS@lycos.com

                #8
                Re: Static variables

                Bruno Desthuilliers:
                And this let you share state between functions:
                >
                def make_counter(st art_at=0, step=1):
                count = [start_at]
                def inc():
                count[0] += step
                return count[0]
                def reset():
                count[0] = [start_at]
                return count[0]
                def peek():
                return count[0]
                >
                return inc, reset, peek
                >
                foo, bar, baaz = make_counter(42 , -1)
                print baaz()
                for x in range(5):
                print foo()
                print bar()
                print baaz()
                An interesting solution, I have never created such grouped clorures. I
                don't know if this solution is better than a class with some class
                attributes plus some class methods...

                Bye,
                bearophile

                Comment

                • Paul Rubin

                  #9
                  Re: Static variables

                  bearophileHUGS@ lycos.com writes:
                  An interesting solution, I have never created such grouped closures. I
                  don't know if this solution is better than a class with some class
                  attributes plus some class methods...
                  It's a Scheme idiom but I think once the object gets this complicated,
                  it's probably more Pythonic to use a class.

                  Comment

                  • Bruno Desthuilliers

                    #10
                    Re: Static variables

                    bearophileHUGS@ lycos.com a écrit :
                    Bruno Desthuilliers:
                    >And this let you share state between functions:
                    >>
                    >def make_counter(st art_at=0, step=1):
                    > count = [start_at]
                    > def inc():
                    > count[0] += step
                    > return count[0]
                    > def reset():
                    > count[0] = [start_at]
                    > return count[0]
                    > def peek():
                    > return count[0]
                    >>
                    > return inc, reset, peek
                    >>
                    >foo, bar, baaz = make_counter(42 , -1)
                    >print baaz()
                    >for x in range(5):
                    > print foo()
                    >print bar()
                    >print baaz()
                    >
                    An interesting solution, I have never created such grouped clorures.
                    It's a common idiom in some functional languages.
                    I
                    don't know if this solution is better than a class with some class
                    attributes plus some class methods...
                    It's somewhat equivalent, but in Python, I'd surely use a class instead !-)

                    Comment

                    Working...