By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,814 Members | 1,136 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,814 IT Pros & Developers. It's quick & easy.

static keyword

P: n/a
I believe the following "static" command would be useful in Python.

def foo():
static i = [10, 11]
static firstcall = True
if firstcall:
print "First pass"
firstcall = False
i[0] += 1
print i[0]
foo()
foo()
This would output:

First pass
11
12

Just like in C, the variables i and firstcall are only assigned the
first time foo() is called. To get this effect currently, one could
use default arguments or wrapping the whole thing in a class. Both of
these solutions seem like hacks, the above method IMO is more
Pythonic. :)

I have a feeling this has been discussed before, but I can't find
anything on it. Thanks,

--Nick
Jul 18 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Nick Jacobson wrote:
I believe the following "static" command would be useful in Python. [snip] Just like in C, the variables i and firstcall are only assigned the
first time foo() is called. To get this effect currently, one could
use default arguments or wrapping the whole thing in a class. Both of
these solutions seem like hacks, the above method IMO is more
Pythonic. :)


I'm not sure how to interpret the smiley, but I'll take it
you weren't actually joking...

Why do you call using OO ("wrapping it in a class", as you say)
a "hack"? Generally speaking, using objects to contain state
information such as this is exactly what most people would call
the cleanest, best approach.

class HasState:
def __init__(self):
self.firstCall = True
self.i = [10, 11]

def foo(self):
if self.firstCall:
print "First pass"
self.firstCall = False
self.i[0] += 1
print self.i[0]

obj = HasState()
obj.foo()
obj.foo()

Now, without arguing that it has 11 lines instead of 8 to do the
same thing (because then I'd just point out that this was a contrived
example anyway, and that it is more easily extended, and more obvious
what was going on, etc. :-) ), can you describe why you call this is
a "hack"?

-Peter
Jul 18 '05 #2

P: n/a
Peter Hansen wrote:
Nick Jacobson wrote:
I believe the following "static" command would be useful in Python.
I do not ! Static variable are like global...
[snip]
Just like in C, the variables i and firstcall are only assigned the
first time foo() is called. To get this effect currently, one could
use default arguments or wrapping the whole thing in a class. Both of
these solutions seem like hacks, the above method IMO is more
Pythonic. :)

or use global with carefully choosed name...

class HasState:
def __init__(self):
self.firstCall = True
self.i = [10, 11]

def foo(self):
if self.firstCall:
print "First pass"
self.firstCall = False
self.i[0] += 1
print self.i[0]

obj = HasState()
obj.foo()
obj.foo()


Like this solution because most of the timethis is not really static
variable that we want but a per context "static" variable.

Anyway, if this is really static variable that you want,
what about this : 8-)
i = [10 ,11]
firstcall = True

def foo(): .... global i
.... global firstcall
.... if firstcall:
.... print "First pass"
.... firstcall = False
.... i[0] += 1
.... print i[0]
.... foo() First pass
11 foo()

12

--
Yermat

Jul 18 '05 #3

P: n/a

"Nick Jacobson" <ni***********@yahoo.com> wrote in message news:f8**************************@posting.google.c om...
| I believe the following "static" command would be useful in Python.
|
| def foo():
| static i = [10, 11]
| static firstcall = True
| if firstcall:
| print "First pass"
| firstcall = False
| i[0] += 1
| print i[0]
| foo()
| foo()
|
|
| This would output:
|
| First pass
| 11
| 12
|
| Just like in C, the variables i and firstcall are only assigned the
| first time foo() is called. To get this effect currently, one could
| use default arguments or wrapping the whole thing in a class. Both of
| these solutions seem like hacks, the above method IMO is more
| Pythonic. :)

"Pythonic" way is to use the oddity of default arguments:

def foo( static_vars = {'i':[10, 11],'firstcall':True} ):
if static_vars['firstcall']:
print "First pass"
static_vars['firstcall'] = False
static_vars['i'][0] += 1
print static_vars['i'][0]
foo()
foo()

--
Georgy
Jul 18 '05 #4

P: n/a
Nick Jacobson wrote:
I believe the following "static" command would be useful in Python. [...] Just like in C, the variables i and firstcall are only assigned the
first time foo() is called. To get this effect currently, one could
use default arguments or wrapping the whole thing in a class. Both of
these solutions seem like hacks, the above method IMO is more
Pythonic. :)


You could also use funtion properties
def statictest (): .... statictest.counter += 1
.... print statictest.counter
.... statictest.counter = 0
statictest () 1 statictest ()

2

But this uses two lookups: one for the function in module scope and one for
the property. Three if you want to do this in a method
(class.method.property).

Just to describe all the possibilities, I probably wouldn't use this myself.

Daniel

Jul 18 '05 #5

P: n/a
>
Why do you call using OO ("wrapping it in a class", as you say)
a "hack"? Generally speaking, using objects to contain state
information such as this is exactly what most people would call
the cleanest, best approach.

class HasState:
def __init__(self):
self.firstCall = True
self.i = [10, 11]

def foo(self):
if self.firstCall:
print "First pass"
self.firstCall = False
self.i[0] += 1
print self.i[0]

obj = HasState()
obj.foo()
obj.foo()

Now, without arguing that it has 11 lines instead of 8 to do the
same thing (because then I'd just point out that this was a contrived
example anyway, and that it is more easily extended, and more obvious
what was going on, etc. :-) ), can you describe why you call this is
a "hack"?

-Peter


I don't know if "hack" is the right word. What I meant is it seems
like overkill to have to make (and name) a class, plus add a second
function, every time you want a function to have a static variable.
Jul 18 '05 #6

P: n/a
> >>> i = [10 ,11]
>>> firstcall = True
>>>
>>> def foo(): ... global i
... global firstcall
... if firstcall:
... print "First pass"
... firstcall = False
... i[0] += 1
... print i[0]
... >>> foo() First pass
11 >>> foo()

12


Hmm. I would like it, but it pollutes the global namespace. Two
functions might want to use firstcall, for example (if they want to
just do something on the first pass). That's an error at most, and
renaming issues at the least.

Thanks for the idea, though..
Jul 18 '05 #7

P: n/a
Nick Jacobson wrote:
I don't know if "hack" is the right word. What I meant is it seems
like overkill to have to make (and name) a class, plus add a second
function, every time you want a function to have a static variable.


I can't recall the last time I wanted a function to have
a static variable. Years, it's been...

(That probably just says something about our approach to design
and coding. I'm not criticizing you, just explaining why what
I showed seems natural and simple to mean, but not to you.)

-Peter
Jul 18 '05 #8

P: n/a
On Thu, Apr 29, 2004 at 12:09:03PM -0700, Nick Jacobson wrote:

Why do you call using OO ("wrapping it in a class", as you say)
a "hack"? Generally speaking, using objects to contain state
information such as this is exactly what most people would call
the cleanest, best approach.

class HasState:
def __init__(self):
self.firstCall = True
self.i = [10, 11]

def foo(self):
if self.firstCall:
print "First pass"
self.firstCall = False
self.i[0] += 1
print self.i[0]

obj = HasState()
obj.foo()
obj.foo()

Now, without arguing that it has 11 lines instead of 8 to do the
same thing (because then I'd just point out that this was a contrived
example anyway, and that it is more easily extended, and more obvious
what was going on, etc. :-) ), can you describe why you call this is
a "hack"?

-Peter


I don't know if "hack" is the right word. What I meant is it seems
like overkill to have to make (and name) a class, plus add a second
function, every time you want a function to have a static variable.


Keeping state in functions is usually a "hack." Class instances have
state, functions just do stuff. That said you can get by just fine
using default arguments for small amounts of state in functions.

def foo(i=[]):
if (not i): # only true once
print "First!"
i.extend([10, 11])
i[0] += 1
print i[0]

But you really really don't want state in plain functions (as opposed
to member functions of objects). I would consider any function that
does something different when called twice with the same arguments broken.
Unless the name of the function starts with 'random' *wink*.

-jackdied
Jul 18 '05 #9

P: n/a
Peter Hansen wrote:
Nick Jacobson wrote:
I believe the following "static" command would be useful in Python.


[snip]
Just like in C, the variables i and firstcall are only assigned the
first time foo() is called. To get this effect currently, one could
use default arguments or wrapping the whole thing in a class. Both of
these solutions seem like hacks, the above method IMO is more
Pythonic. :)

I'm not sure how to interpret the smiley, but I'll take it
you weren't actually joking...

Why do you call using OO ("wrapping it in a class", as you say)
a "hack"? Generally speaking, using objects to contain state
information such as this is exactly what most people would call
the cleanest, best approach.
[...]

There's also a bunch of people who would consider this (modulo my
obvious mistakes ;) the cleanest, best approach:

(let ((first-call #t)
(i '(10 11)))
(define (foo)
(when (first-call)
(begin (display "first pass") (set! first-call #f))
(set! (array-ref i 0) (+ (array-ref i 0) 1))
(display (array-ref i 0))))

I.e. capture the state in a normal lexical variable.

Cheers,
Michael
Jul 18 '05 #10

P: n/a
Peter <pe***@engcorp.com> wrote on 04/29/04 at 14:37:
I'm not sure how to interpret the smiley, but I'll take it
you weren't actually joking... Why do you call using OO ("wrapping it in a class", as you say)
a "hack"? Generally speaking, using objects to contain state
information such as this is exactly what most people would call
the cleanest, best approach.


I'm not the original poster, but I'm going to side with him.

Class, to me, implies a fair number of things about the intended
use of what the author has written. Jacobson is talking about
a much simpler construct/feature than what one would normally
use a class for. His proposal might seem like mere syntactic
sugar to avoid making a class, but IMHO it will lead to code
that is more readable - code that doesn't imply it's anything
other than a function with a persistant, stateful variable.

Steve
Jul 18 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.