Static Variables in Python?

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

    #1

    Static Variables in Python?

    Is it possible to have a static variable in Python -
    a local variable in a function that retains its value.

    For example, suppose I have:

    def set_bit (bit_index, bit_value):
    static bits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    bits [bit_index] = bit_value

    print "\tBit Array:"
    int i
    while (i < len(bits):
    print bits[i],
    print '\n'


    I realize this can be implemented by making bits global, but can
    this be done by making it private only internal to set_bit()? I don't
    want bits to be reinitialized each time. It must retain the set values
    for the next time it is called.


    Thanks in advance:
    Michael Yanowitz



  • Roel Schroeven

    #2
    Re: Static Variables in Python?

    Michael Yanowitz schreef:
    Is it possible to have a static variable in Python -
    a local variable in a function that retains its value.
    >
    For example, suppose I have:
    >
    def set_bit (bit_index, bit_value):
    static bits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    bits [bit_index] = bit_value
    >
    print "\tBit Array:"
    int i
    while (i < len(bits):
    print bits[i],
    print '\n'
    >
    >
    I realize this can be implemented by making bits global, but can
    this be done by making it private only internal to set_bit()? I don't
    want bits to be reinitialized each time. It must retain the set values
    for the next time it is called.
    You could do it by defining static_bits as a keyword parameter with a
    default value:
    >>def set_bit(bit_ind ex, bit_value, static_bits=[0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0]):
    static_bits[bit_index] = bit_value
    return static_bits
    >>set_bit(2, 1)
    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    >>set_bit(3, 1)
    [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    >>set_bit(2, 0)
    [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

    It might be a better idea to use a class for this though:
    >>class Bits(object):
    def __init__(self):
    self.bits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    def set(self, index, value):
    self.bits[index] = value
    return self.bits

    >>bits = Bits()
    >>bits.set(2, 1)
    [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    >>bits.set(3, 1)
    [0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    >>bits.set(2, 0)
    [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

    When using a class, you can have different lists of bits independently
    of each other in a program. And you can define other operations on the
    bits: you could for example create methods to set or clear all bits at
    once. With your approach, set_bit is the only function that has access
    to the bits so you can't easily create other operations.

    --
    If I have been able to see further, it was only because I stood
    on the shoulders of giants. -- Isaac Newton

    Roel Schroeven

    Comment

    • tac-tics

      #3
      Re: Static Variables in Python?


      Michael Yanowitz wrote:
      Is it possible to have a static variable in Python -
      a local variable in a function that retains its value.
      >
      For example, suppose I have:
      >
      def set_bit (bit_index, bit_value):
      static bits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
      bits [bit_index] = bit_value
      >
      print "\tBit Array:"
      int i
      while (i < len(bits):
      print bits[i],
      print '\n'
      >
      >
      I realize this can be implemented by making bits global, but can
      this be done by making it private only internal to set_bit()? I don't
      want bits to be reinitialized each time. It must retain the set values
      for the next time it is called.
      If you declare bits in set_bit() as "global bits = ...", it will create
      it as a global variable without you having to declare it outside of the
      function. Just be careful about name conflicts.

      Comment

      • bearophileHUGS@lycos.com

        #4
        Re: Static Variables in Python?

        tac-tics:
        If you declare bits in set_bit() as "global bits = ...", it will create
        it as a global variable without you having to declare it outside of the
        function. Just be careful about name conflicts.
        Are you sure?

        def fun():
        global x = 10
        fun()
        print x

        Bye,
        bearophile

        Comment

        • John Salerno

          #5
          Re: Static Variables in Python?

          bearophileHUGS@ lycos.com wrote:
          tac-tics:
          >If you declare bits in set_bit() as "global bits = ...", it will create
          >it as a global variable without you having to declare it outside of the
          >function. Just be careful about name conflicts.
          >
          Are you sure?
          >
          def fun():
          global x = 10
          fun()
          print x
          >
          Bye,
          bearophile
          >
          This works for me:
          >>def fun():
          global x
          x = 10

          >>fun()
          >>print x
          10
          >>>
          But of course:
          >>def fun():
          global x = 10

          SyntaxError: invalid syntax
          >>>

          Comment

          • Bruno Desthuilliers

            #6
            Re: Static Variables in Python?

            Roel Schroeven a écrit :
            Michael Yanowitz schreef:
            >
            > Is it possible to have a static variable in Python - a local
            >variable in a function that retains its value.
            >>
            (snip)
            >
            You could do it by defining static_bits as a keyword parameter with a
            default value:
            >
            (snip)
            It might be a better idea to use a class for this though:
            >
            (snip)

            Last solution being to use a closure:

            def make_bits():
            bits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
            def set_bit(bit_ind ex, bit_value):
            bits[bit_index] = bit_values
            def get_bits():
            # returns a copy so we don't overwrite
            return bits[:]
            return set_bit, get_bits

            set_bit, get_bits = make_bits()

            But the better solution is probably to make it a class.

            Comment

            • Bruno Desthuilliers

              #7
              Re: Static Variables in Python?

              Michael Yanowitz a écrit :
              Is it possible to have a static variable in Python -
              a local variable in a function that retains its value.
              >
              For example, suppose I have:
              >
              def set_bit (bit_index, bit_value):
              static bits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
              bits [bit_index] = bit_value
              >
              print "\tBit Array:"
              int i
              Syntax error
              while (i < len(bits):
              print bits[i],
              Nice infinite loop...

              Python's canonical way to iterate over a sequence is the for loop:
              for bit in bits:
              print bit,

              And FWIW, for what you want to do, you don't even need a loop:
              print "\n".join(map(s tr, bits))
              print '\n'
              >
              I realize this can be implemented by making bits global, but can
              this be done by making it private only internal to set_bit()? I don't
              want bits to be reinitialized each time. It must retain the set values
              for the next time it is called.
              While there are some more or less hackish solutions (cf Roel answers and
              my answers to it), the usual way to have functions maintaining state is
              to define a class and instanciate it. Note that Python's functions are
              objects, and that it's possible to write your own callable objects too
              if you really want a function call syntax:

              class Setbit(object):
              def __init__(self):
              self._bits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
              def call(self, index, value):
              self._bits[index] = value
              def values(self):
              return self._bits[:]

              set_bit = Setbit()
              set_bit(1, 1)
              print "".join(map(str , set_bit.values( )))

              Comment

              • Paddy

                #8
                Re: Static Variables in Python?


                Michael Yanowitz wrote:
                Is it possible to have a static variable in Python -
                a local variable in a function that retains its value.
                >
                For example, suppose I have:
                >
                def set_bit (bit_index, bit_value):
                static bits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
                bits [bit_index] = bit_value
                >
                print "\tBit Array:"
                int i
                while (i < len(bits):
                print bits[i],
                print '\n'
                >
                >
                I realize this can be implemented by making bits global, but can
                this be done by making it private only internal to set_bit()? I don't
                want bits to be reinitialized each time. It must retain the set values
                for the next time it is called.
                >
                >
                Thanks in advance:
                Michael Yanowitz
                You can do things with function attributes

                def foo(x):
                foo.static += x
                return foo.static
                foo.static = 0

                If you are going to set function attributes a lot, then you might like
                to addd an attriute setter decorator to your toolbox:

                def attributeSetter ( **kw):
                " decorator creator: initialises function attributes"
                def func2(func):
                " decorator: initialises function attributes"
                func.__dict__.u pdate(kw)
                return func
                return func2

                def accumulator(n):
                """ return an accumulator function that starts at n
                >>x3 = accumulator(3)
                >>x3.acc
                3
                >>x3(4)
                7
                >>x3.acc
                7
                """
                @attributeSette r(acc = n)
                def accum(i):
                accum.acc+= i
                return accum.acc
                return accum


                - Paddy

                Comment

                • tac-tics

                  #9
                  Re: Static Variables in Python?

                  But of course:
                  >
                  >>def fun():
                  global x = 10
                  >
                  SyntaxError: invalid syntax
                  >>>
                  global x
                  x = 10

                  Close enough ^^;

                  Comment

                  • Cameron Laird

                    #10
                    Re: Static Variables in Python?

                    In article <1154378719.157 643.98340@p79g2 000cwp.googlegr oups.com>,
                    Paddy <paddy3118@nets cape.netwrote:

                    Comment

                    • Paddy

                      #11
                      Re: Static Variables in Python?


                      Cameron Laird wrote:
                      In article <1154378719.157 643.98340@p79g2 000cwp.googlegr oups.com>,
                      Paddy <paddy3118@nets cape.netwrote:
                      .
                      [substantial thread
                      with many serious
                      alternatives]
                      .
                      .
                      You can do things with function attributes

                      def foo(x):
                      foo.static += x
                      return foo.static
                      foo.static = 0
                      .
                      .
                      .
                      My favorite variation is this:
                      >
                      def accumulator(x):
                      # On first execution, the attribute is not yet known.
                      # This technique allows use of accumulator() as a
                      # function without the "consumer" having to initialize
                      # it.
                      if not "static" in dir(accumulator ):
                      accumulator.sta tic = 0
                      accumulator.sta tic += x
                      return accumulator.sta tic
                      >
                      print accumulator(3)
                      print accumulator(5)
                      Thanks Cameron, I'll accumulate this in my toolbox.

                      - pad.

                      Comment

                      Working...