static variables in Python?

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

    static variables in Python?



    Yet another noob question...

    Is there a way to mimic C's static variables in Python? Or something
    like it? The idea is to equip a given function with a set of
    constants that belong only to it, so as not to clutter the global
    namespace with variables that are not needed elsewhere.

    For example, in Perl one can define a function foo like this

    *foo = do {
    my $x = expensive_call( );
    sub {
    return do_stuff_with( $x, @_ );
    }
    };

    In this case, foo is defined by assigning to it a closure that has
    an associated variable, $x, in its scope.

    Is there an equivalent in Python?

    Thanks!

    kynn
    --
    NOTE: In my address everything before the first period is backwards;
    and the last period, and everything after it, should be discarded.
  • Larry Bates

    #2
    Re: static variables in Python?

    kj wrote:
    Yet another noob question...
    >
    Is there a way to mimic C's static variables in Python? Or something
    like it? The idea is to equip a given function with a set of
    constants that belong only to it, so as not to clutter the global
    namespace with variables that are not needed elsewhere.
    >
    For example, in Perl one can define a function foo like this
    >
    *foo = do {
    my $x = expensive_call( );
    sub {
    return do_stuff_with( $x, @_ );
    }
    };
    >
    In this case, foo is defined by assigning to it a closure that has
    an associated variable, $x, in its scope.
    >
    Is there an equivalent in Python?
    >
    Thanks!
    >
    kynn

    First names in Python are just that, names that point to objects. Those objects
    can contain any type of information including other objects. They are NOT
    buckets where things are stored.

    1) Names (variables in Perl/C) defined within a Python function are placed in
    its local namespace. They are not visible in the global namespace.

    2) Yes you can have a local name point to a global. This is often used in
    classes with attributes because looking up local is somewhat quicker than
    looking up the class attribute.

    def foo():
    x = expensive_call
    return do_stuff_with(x ())

    In this particular case it doesn't really help.

    It would be more useful in something like:

    class foo(object):
    def __init__(self, initialvalue = 0)
    self.currentval ue = initialvalue

    def longloopingmeth od(self, listtosum):
    currentvalue = self.currentval ue
    for v in listtosum:
    currentvalue += v


    BTW - There are BETTER ways to sum a list, so this is just an example.

    -Larry

    Comment

    • kj

      #3
      Re: static variables in Python?

      In <w8CdnQGPtuvdGR LVnZ2dnUVZ_r7in Z2d@comcast.com Larry Bates <larry.bates@we bsafe.com`write s:
      >kj wrote:
      >Yet another noob question...
      >>
      >Is there a way to mimic C's static variables in Python? Or something
      >like it? The idea is to equip a given function with a set of
      >constants that belong only to it, so as not to clutter the global
      >namespace with variables that are not needed elsewhere.
      >>
      >For example, in Perl one can define a function foo like this
      >>
      >*foo = do {
      > my $x = expensive_call( );
      > sub {
      > return do_stuff_with( $x, @_ );
      > }
      >};
      >>
      >In this case, foo is defined by assigning to it a closure that has
      >an associated variable, $x, in its scope.
      >>
      >Is there an equivalent in Python?
      >>
      >Thanks!
      >>
      >kynn
      >First names in Python are just that, names that point to objects. Those objects
      >can contain any type of information including other objects. They are NOT
      >buckets where things are stored.
      >1) Names (variables in Perl/C) defined within a Python function are placed in
      >its local namespace. They are not visible in the global namespace.
      >2) Yes you can have a local name point to a global. This is often used in
      >classes with attributes because looking up local is somewhat quicker than
      >looking up the class attribute.
      >def foo():
      x = expensive_call
      return do_stuff_with(x ())
      Maybe I'm missing your point, the goal is to have a "runtime
      constant" associated with the function. In the your definition of
      foo, expensive_call gets called every time that foo gets called;
      this is what I'm trying to avoid!

      Maybe it's easier to see what I mean with JavaScript:

      function foo() {
      if (foo.x === undefined) foo.x = expensive_call( );
      return do_stuff_with(f oo.x);
      }

      Here, expensive_call is called only once (assuming it never returns
      undefined).

      OK, I guess that in Python the only way to do what I want to do is
      with objects...

      kynn
      --
      NOTE: In my address everything before the first period is backwards;
      and the last period, and everything after it, should be discarded.

      Comment

      • Colin J. Williams

        #4
        Re: static variables in Python?

        kj wrote:
        In <w8CdnQGPtuvdGR LVnZ2dnUVZ_r7in Z2d@comcast.com Larry Bates <larry.bates@we bsafe.com`write s:
        >
        >kj wrote:
        >>Yet another noob question...
        >>>
        >>Is there a way to mimic C's static variables in Python? Or something
        >>like it? The idea is to equip a given function with a set of
        >>constants that belong only to it, so as not to clutter the global
        >>namespace with variables that are not needed elsewhere.
        >>>
        >>For example, in Perl one can define a function foo like this
        >>>
        >>*foo = do {
        >> my $x = expensive_call( );
        >> sub {
        >> return do_stuff_with( $x, @_ );
        >> }
        >>};
        >>>
        >>In this case, foo is defined by assigning to it a closure that has
        >>an associated variable, $x, in its scope.
        >>>
        >>Is there an equivalent in Python?
        >>>
        >>Thanks!
        >>>
        >>kynn
        >
        >
        >First names in Python are just that, names that point to objects. Those objects
        >can contain any type of information including other objects. They are NOT
        >buckets where things are stored.
        >
        >1) Names (variables in Perl/C) defined within a Python function are placed in
        >its local namespace. They are not visible in the global namespace.
        >
        >2) Yes you can have a local name point to a global. This is often used in
        >classes with attributes because looking up local is somewhat quicker than
        >looking up the class attribute.
        >
        >def foo():
        > x = expensive_call
        > return do_stuff_with(x ())
        >
        Maybe I'm missing your point, the goal is to have a "runtime
        constant" associated with the function. In the your definition of
        foo, expensive_call gets called every time that foo gets called;
        this is what I'm trying to avoid!
        >
        Maybe it's easier to see what I mean with JavaScript:
        >
        function foo() {
        if (foo.x === undefined) foo.x = expensive_call( );
        return do_stuff_with(f oo.x);
        }
        >
        Here, expensive_call is called only once (assuming it never returns
        undefined).
        >
        OK, I guess that in Python the only way to do what I want to do is
        with objects...
        >
        kynn
        You might consider using a singleton class.

        Colin W.

        Comment

        • bearophileHUGS@lycos.com

          #5
          Re: static variables in Python?

          kj:
          OK, I guess that in Python the only way to do what I want to do
          is with objects...
          There are other ways, like assigning the value out of the function,
          because Python functions too are objects:

          def iamslow():
          return 100
          def foo(x):
          return x + foo.y
          foo.y = iamslow() # slow computation
          print foo(1)
          print foo(2)

          Output is:
          101
          102

          Another way is this, a bit more clean, with the same output:

          def iamslow():
          return 100
          def foo(x, y=iamslow()):
          return x + y
          print foo(1)
          print foo(2)

          But I suggest you to use a class in this situation, it's often the way
          that will keep your code more bug-free, and more readable by near-
          casual readers too. Python philosophy asks you to write readable code
          instead of clever code when possible, this is a difference from Perl,
          I presume.

          Bye,
          bearophile

          Comment

          • Ben Finney

            #6
            Re: static variables in Python?

            kj <socyl@987jk.co m.invalidwrites :
            Is there a way to mimic C's static variables in Python? Or something
            like it?
            A "static variable" in C is one that has access limited to the scope
            in which it is declared.

            Python approaches the same issue through namespaces: a name binding
            made at a class or module level is accessible only via specification
            of the class or module namespace.
            The idea is to equip a given function with a set of constants that
            belong only to it, so as not to clutter the global namespace with
            variables that are not needed elsewhere.
            Python functions have local name bindings by default
            <URL:http://www.python.org/doc/current/ref/naming.html>.

            Python doesn't have "variables" in the sense of boxes containing
            values, so it doesn't have "constants" in the sense of boxes that
            don't change. Instead, Python has names bound to objects like sticky
            notes. A name can later be re-bound to some other object.

            What use case are you trying to address? It seems that the normal use
            of local function names and class attributes would serve your
            described requirements.

            --
            \ “It is hard to believe that a man is telling the truth when you |
            `\ know that you would lie if you were in his place.” —Henry L. |
            _o__) Mencken |
            Ben Finney

            Comment

            • Bruce Frederiksen

              #7
              Re: static variables in Python?

              On Tue, 29 Jul 2008 21:31:01 +0000, kj wrote:
              In <w8CdnQGPtuvdGR LVnZ2dnUVZ_r7in Z2d@comcast.com Larry Bates <larry.bates@we bsafe.com`write s:
              >
              [snip]
              >
              Maybe it's easier to see what I mean with JavaScript:
              >
              function foo() {
              if (foo.x === undefined) foo.x = expensive_call( );
              return do_stuff_with(f oo.x);
              }
              def foo():
              if not hasattr(foo, 'x'): foo.x = expensive_call( )
              return do_stuff_with(f oo.x)

              or, maybe just define foo in two steps:

              def foo():
              return do_stuff_with(f oo.x)

              foo.x = expensive_call( )

              Comment

              • Russ P.

                #8
                Re: static variables in Python?

                On Jul 29, 1:40 pm, kj <so...@987jk.co m.invalidwrote:
                Yet another noob question...
                >
                Is there a way to mimic C's static variables in Python? Or something
                like it? The idea is to equip a given function with a set of
                constants that belong only to it, so as not to clutter the global
                namespace with variables that are not needed elsewhere.
                >
                For example, in Perl one can define a function foo like this
                >
                *foo = do {
                my $x = expensive_call( );
                sub {
                return do_stuff_with( $x, @_ );
                }
                >
                };
                >
                In this case, foo is defined by assigning to it a closure that has
                an associated variable, $x, in its scope.
                >
                Is there an equivalent in Python?
                >
                Thanks!
                >
                kynn
                --
                NOTE: In my address everything before the first period is backwards;
                and the last period, and everything after it, should be discarded.
                If the constant parameters are really only needed in one particular
                function, you can use default function arguments. An added benefit is
                that you can override them with another value if necessary.

                def fun(x, y, parameter1=0, parameter2=1):
                ...

                Comment

                • pigmartian

                  #9
                  Re: static variables in Python?

                  bearophileHUGS@ lycos.com wrote:
                  kj:
                  >OK, I guess that in Python the only way to do what I want to do
                  >is with objects...
                  >
                  There are other ways, like assigning the value out of the function,
                  because Python functions too are objects:
                  >
                  ....
                  But I suggest you to use a class in this situation, it's often the way
                  that will keep your code more bug-free, and more readable by near-
                  casual readers too. Python philosophy asks you to write readable code
                  instead of clever code when possible, this is a difference from Perl,
                  I presume.
                  >
                  Bye,
                  bearophile
                  Here's a solution using decorators, I like it, but I'm biased:

                  def staticAttrs(**k wds):
                  """
                  Adds attributes to a function, akin to c-style
                  "static" variables
                  """

                  def _decorator(fcn) :
                  for k in kwds:
                  setattr(fcn, k, kwds[k])
                  return fcn
                  return _decorator



                  @staticAttrs(n= 0)
                  def rememberCalls() :
                  """
                  >>rememberCalls ()
                  0
                  >>rememberCalls ()
                  1
                  >>rememberCalls ()
                  2
                  """
                  print rememberCalls.n
                  rememberCalls.n += 1

                  ~Scott

                  Comment

                  • Russ P.

                    #10
                    Re: static variables in Python?

                    On Jul 29, 6:33 pm, "Russ P." <Russ.Paie...@g mail.comwrote:
                    On Jul 29, 1:40 pm, kj <so...@987jk.co m.invalidwrote:
                    >
                    >
                    >
                    Yet another noob question...
                    >
                    Is there a way to mimic C's static variables in Python? Or something
                    like it? The idea is to equip a given function with a set of
                    constants that belong only to it, so as not to clutter the global
                    namespace with variables that are not needed elsewhere.
                    >
                    For example, in Perl one can define a function foo like this
                    >
                    *foo = do {
                    my $x = expensive_call( );
                    sub {
                    return do_stuff_with( $x, @_ );
                    }
                    >
                    };
                    >
                    In this case, foo is defined by assigning to it a closure that has
                    an associated variable, $x, in its scope.
                    >
                    Is there an equivalent in Python?
                    >
                    Thanks!
                    >
                    kynn
                    --
                    NOTE: In my address everything before the first period is backwards;
                    and the last period, and everything after it, should be discarded.
                    >
                    If the constant parameters are really only needed in one particular
                    function, you can use default function arguments. An added benefit is
                    that you can override them with another value if necessary.
                    >
                    def fun(x, y, parameter1=0, parameter2=1):
                    ...
                    I should add that the parameters need not be literal numbers. They can
                    be computed values as well. They will be computed only once, on the
                    first pass through the function definition, which I presume is exactly
                    what you want.

                    I think this is the simplest solution to the problem you posed.


                    Comment

                    • John Machin

                      #11
                      Re: static variables in Python?

                      On Jul 30, 11:57 am, "Russ P." <Russ.Paie...@g mail.comwrote:
                      On Jul 29, 6:33 pm, "Russ P." <Russ.Paie...@g mail.comwrote:
                      >
                      >
                      >
                      On Jul 29, 1:40 pm, kj <so...@987jk.co m.invalidwrote:
                      >
                      Yet another noob question...
                      >
                      Is there a way to mimic C's static variables in Python? Or something
                      like it? The idea is to equip a given function with a set of
                      constants that belong only to it, so as not to clutter the global
                      namespace with variables that are not needed elsewhere.
                      >
                      For example, in Perl one can define a function foo like this
                      >
                      *foo = do {
                      my $x = expensive_call( );
                      sub {
                      return do_stuff_with( $x, @_ );
                      }
                      >
                      };
                      >
                      In this case, foo is defined by assigning to it a closure that has
                      an associated variable, $x, in its scope.
                      >
                      Is there an equivalent in Python?
                      >
                      Thanks!
                      >
                      kynn
                      --
                      NOTE: In my address everything before the first period is backwards;
                      and the last period, and everything after it, should be discarded.
                      >
                      If the constant parameters are really only needed in one particular
                      function, you can use default function arguments. An added benefit is
                      that you can override them with another value if necessary.
                      >
                      def fun(x, y, parameter1=0, parameter2=1):
                      ...
                      >
                      I should add that the parameters need not be literal numbers. They can
                      be computed values as well. They will be computed only once, on the
                      first pass through the function definition, which I presume is exactly
                      what you want.
                      >
                      I think this is the simplest solution to the problem you posed.
                      Here's a real-life example, where the second and third args are run-
                      time constants:

                      def unescape(s,
                      subber=re.compi le(r'_x[0-9A-Fa-f]{4,4}_').sub,
                      repl=lambda mobj: unichr(int(mobj .group(0)[2:6], 16)),
                      ):
                      if "_" in s:
                      return subber(repl, s)
                      return s
                      # The if test is just an optimisation that unfortunately the re module
                      doesn't nut out for itself.

                      Cheers,
                      John

                      Comment

                      • castironpi

                        #12
                        Re: static variables in Python?

                        On Jul 29, 8:38 pm, pigmartian <scottp...@comc ast.netwrote:
                        bearophileH...@ lycos.com wrote:
                        kj:
                        OK, I guess that in Python the only way to do what I want to do
                        is with objects...
                        >
                        There are other ways, like assigning the value out of the function,
                        because Python functions too are objects:
                        >
                        ...
                        But I suggest you to use a class in this situation, it's often the way
                        that will keep your code more bug-free, and more readable by near-
                        casual readers too. Python philosophy asks you to write readable code
                        instead of clever code when possible, this is a difference from Perl,
                        I presume.
                        >
                        Bye,
                        bearophile
                        >
                        Here's a solution using decorators, I like it, but I'm biased:
                        >
                        def staticAttrs(**k wds):
                                """
                                Adds attributes to a function, akin to c-style
                                "static" variables
                                """
                        >
                                def _decorator(fcn) :
                                        for k in kwds:
                                                setattr(fcn, k, kwds[k])
                                        return fcn
                                return _decorator
                        >
                        @staticAttrs(n= 0)
                        def rememberCalls() :
                                """
                                >>rememberCalls ()
                                0
                                >>rememberCalls ()
                                1
                                >>rememberCalls ()
                                2
                                """
                                print rememberCalls.n
                                rememberCalls.n += 1
                        >
                        ~Scott
                        I like it too. It also thought of (implementation not shown):

                        @has_locals
                        def rememberCalls( self ):
                        self.val= 0
                        self.ref= object( )

                        where self is preserved between calls and is an instance of a custom
                        class, possibly empty. If you want more than one, but still
                        preserved:

                        rememberCallsA= has_locals( rememberCalls )
                        rememberCallsB= has_locals( rememberCalls )

                        You might want to make self a small and lightweight dict-only object:

                        @has_locals
                        def rememberCalls( dic ):
                        dic['val']= 0
                        dic['ref']= object( )

                        Comment

                        • Daniel da Silva

                          #13
                          Re: static variables in Python?

                          This is the solution I suggest. It is fairly trivial, and works by
                          introducing the "self.stati c" namespace for a class's static
                          variables, in contrast to "self" for the class's instance variables.

                          -----------------------------------

                          class Static(object): pass
                          personStatic = Static()

                          class Person:
                          static = personStatic

                          def __init__(self, name, age):
                          self.name = name
                          self.age = age

                          def setVersion(self , version):
                          self.static.ver sion = version

                          def getVersion(self ):
                          return self.static.ver sion
                          -----------------------------------

                          Daniel

                          On Tue, Jul 29, 2008 at 4:40 PM, kj <socyl@987jk.co m.invalidwrote:
                          >
                          >
                          Yet another noob question...
                          >
                          Is there a way to mimic C's static variables in Python? Or something
                          like it? The idea is to equip a given function with a set of
                          constants that belong only to it, so as not to clutter the global
                          namespace with variables that are not needed elsewhere.
                          >
                          For example, in Perl one can define a function foo like this
                          >
                          *foo = do {
                          my $x = expensive_call( );
                          sub {
                          return do_stuff_with( $x, @_ );
                          }
                          };
                          >
                          In this case, foo is defined by assigning to it a closure that has
                          an associated variable, $x, in its scope.
                          >
                          Is there an equivalent in Python?
                          >
                          Thanks!
                          >
                          kynn
                          --
                          NOTE: In my address everything before the first period is backwards;
                          and the last period, and everything after it, should be discarded.
                          --

                          >

                          Comment

                          • Rhamphoryncus

                            #14
                            Re: static variables in Python?

                            On Jul 29, 2:40 pm, kj <so...@987jk.co m.invalidwrote:
                            Yet another noob question...
                            >
                            Is there a way to mimic C's static variables in Python?  Or something
                            like it?  The idea is to equip a given function with a set of
                            constants that belong only to it, so as not to clutter the global
                            namespace with variables that are not needed elsewhere.
                            I'd go ahead and use globals. If these really are constant you should
                            just name them clearly (and possibly use all caps).

                            If they have a possibility of becoming non-constant in the future,
                            write a class. No fancy tricks needed to store state.

                            Comment

                            • 5lvqbwl02@sneakemail.com

                              #15
                              Re: static variables in Python?




                              kj wrote:
                              Yet another noob question...
                              >
                              Is there a way to mimic C's static variables in Python? Or something
                              like it? The idea is to equip a given function with a set of
                              constants that belong only to it, so as not to clutter the global
                              namespace with variables that are not needed elsewhere.
                              >
                              For example, in Perl one can define a function foo like this
                              >
                              *foo = do {
                              my $x = expensive_call( );
                              sub {
                              return do_stuff_with( $x, @_ );
                              }
                              };
                              >
                              In this case, foo is defined by assigning to it a closure that has
                              an associated variable, $x, in its scope.
                              >
                              Is there an equivalent in Python?
                              >


                              I found the following link addressing this problem several different
                              ways. My favorite (trickiest) way is using decorators...



                              Comment

                              Working...