Re: C-style static variables in Python?

2010-04-15 Thread Albert van der Horst
In article mailman.1441.1270165718.23598.python-l...@python.org,
Steve Holden  st...@holdenweb.com wrote:
Terry Reedy wrote:
 On 4/1/2010 6:34 PM, kj wrote:


 When coding C I have often found static local variables useful for
 doing once-only run-time initializations.  For example:

 int foo(int x, int y, int z) {

static int first_time = TRUE;
static Mongo *mongo;
if (first_time) {
  mongo = heavy_lifting_at_runtime();
  first_time = FALSE;
}

return frobnicate(mongo, x, y, z);

 Global var or class or closure such as below (obviously untested ;=):

 make_foo()
   mongo = heavy_lifting_at_runtime();
   def _(x,y,z):
 return frobnicate(mongo, x, y, z)
   return _
 foo = make_foo

I suspect you mean

foo = make_foo()

 del make_foo # to make sure it is *never* called again ;

 Now you only have foo with a hard-to-access private object and no
 first_time checks when you call it.

 Terry Jan Reedy

I don't think I'd ever want to use such an obscure technique in a
program. You might want to consider using functools.wraps to make sure
that the foo function looks right.

Imagine that heavy_lifting is only ever used here and uses 4 Gbyte of core.
Suddenly deleting those function objects seems the right thing to do,
instead of an obscure technique.
(I'm not sure the Python compiler could take advantage of this,
I know I could in my Forth compiler, under circumstances.)


regards
 Steve
--
Steve Holden   +1 571 484 6266   +1 800 494 3119

Groetjes Albert

--
-- 
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
alb...@spearc.xs4all.nl =n http://home.hccnet.nl/a.w.m.van.der.horst

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-05 Thread Lee Harr

 Another approach would be to stuff the static values in the function's
 __dict__.

That's how I did it when I wanted something similar.

I created this decorator:


def static(**kw):
    '''
    Used to create a decorator function that will add an
    attribute to a function and initialize it.

    @static(foo=5)
    ... def bar():
    ... print bar.foo
    ... bar.foo += 1
    ...
    bar()
    5
    bar()
    6
    '''

    def decorator(f):
    f.__dict__.update(kw)
    return f
    return decorator

  
_
Hotmail: Trusted email with Microsoft’s powerful SPAM protection.
https://signup.live.com/signup.aspx?id=60969
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-05 Thread Ethan Furman

Ethan Furman wrote:

Steven D'Aprano wrote:

On Fri, 02 Apr 2010 19:48:59 -0700, Ethan Furman wrote:



The heuristic I use is, if I expect the try block to raise an exception
more than about one time in ten, I change to an explicit test. In this
case, since the exception should only be raised once, and then never
again, I would use a try...except block.


That was my reasoning as well, but when I timed it for one million runs
(so 1 instantiation, 999,999 simple calls), the __getattr__ time was .5
seconds, the try...execpt block was .6; at ten million it was 5 and 6.



Care to share your timing code? Not that I don't trust your results, 
but timings are very sensitive to the exact thing you do, and I'd like 
to see what that is.


Happy to do so -- if I made a mistake I'd like to know about it and learn.

It'll have to wait two days 'til I get back to work, though... I'll post 
it asap.


Well, so much for asap, but here's what I used (with one correction: in 
the 'if' code I had forgotten to actually reference the missing 
attribute, so the __getattr__ look up never happened; now the 
try...except block is /slightly/ faster, as opposed to 20% slower).



class spam_except(object):
def __call__(self, x, y, z):
try:
mongo = self.mongo
except AttributeError:
mongo = self.mongo = 1
return

class spam_if(object):
def __getattr__(self, name):
if name != 'mongo':
raise AttributeError
self.mongo = 1
return self.mongo
def __call__(self, x, y, z):
self.mongo  # didn't have this line before.  d'oh!
return


-- timeit.Timer('spammer(1,2,3)','from spam import spam_except; 
spammer=spam_except()').timeit()

0.65764130543749388

-- timeit.Timer('spammer(1,2,3)','from spam import spam_if; 
spammer=spam_if()').timeit()

0.66972877235545525

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-05 Thread Patrick Maupin
On Apr 5, 6:50 pm, Ethan Furman et...@stoneleaf.us wrote:

(Posted some code with a timeit...)

Well, I'm not going to debug this, but with the *original* thing you
posted, and the thing I posted, with a call and everything (more
realistic scenario), the exception version seems slower on my machine:

#!/usr/bin/env python

import timeit

def frobnicate(a,b,c,d):
pass

def heavy_lifting_at_runtime():
print 'heavy'

class spam_except(object):
 def __call__(self, x, y, z):
 try:
 mongo = self.mongo
 except AttributeError:
 mongo = self.mongo = heavy_lifting_at_runtime()
 return frobnicate(x, y, z, mongo)
se = spam_except()


class spam_if(object):
 def __getattr__(self, name):
 if name != 'mongo':
 raise AttributeError
 self.mongo = heavy_lifting_at_runtime()
 return self.mongo
 def __call__(self, x, y, z):
 return frobnicate(x, y, z, self.mongo)
si = spam_if()

tse = timeit.Timer('se(1,2,3)', from __main__ import se)
tsi = timeit.Timer('si(1,2,3)', from __main__ import si)

for i in range(5):
ve = tse.timeit(1000)
vi = tsi.timeit(1000)
print ve, vi, '%.1f' % ((ve-vi) / vi * 100)

--

heavy
heavy
5.45695090294 5.10844397545 6.8
5.43381404877 5.01345705986 8.4
5.42474508286 5.02641201019 7.9
5.40713405609 5.04178905487 7.2
5.38063693047 4.96194696426 8.4

The output indicates that the exception one is, on average, around
7.5% slower.

Regards,
Pat
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-04 Thread John Nagle

kj wrote:

When coding C I have often found static local variables useful for
doing once-only run-time initializations. 


   If you want functions with state, use an object. That's what they're
for.  Don't muck with the internal representation of functions.

John Nagle
--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-04 Thread Patrick Maupin
On Apr 4, 1:57 pm, John Nagle na...@animats.com wrote:
     If you want functions with state, use an object. That's what they're
 for.  Don't muck with the internal representation of functions.


While Don't muck with the internal representation of functions is
excellent advice over 99% of the time, it is also true that it is
often possible, sometimes even encouraged, to have functions with
state.

This is done without mucking and without explicitly declaring a
class or a class instance.  See, e.g. closures and generator
functions.

Regards,
Pat
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-03 Thread Steven D'Aprano
On Fri, 02 Apr 2010 19:48:59 -0700, Ethan Furman wrote:

 The heuristic I use is, if I expect the try block to raise an exception
 more than about one time in ten, I change to an explicit test. In this
 case, since the exception should only be raised once, and then never
 again, I would use a try...except block.
 
 That was my reasoning as well, but when I timed it for one million runs
 (so 1 instantiation, 999,999 simple calls), the __getattr__ time was .5
 seconds, the try...execpt block was .6; at ten million it was 5 and 6.

Care to share your timing code? Not that I don't trust your results, but 
timings are very sensitive to the exact thing you do, and I'd like to see 
what that is.




-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-03 Thread Ethan Furman

Steven D'Aprano wrote:

On Fri, 02 Apr 2010 19:48:59 -0700, Ethan Furman wrote:



The heuristic I use is, if I expect the try block to raise an exception
more than about one time in ten, I change to an explicit test. In this
case, since the exception should only be raised once, and then never
again, I would use a try...except block.


That was my reasoning as well, but when I timed it for one million runs
(so 1 instantiation, 999,999 simple calls), the __getattr__ time was .5
seconds, the try...execpt block was .6; at ten million it was 5 and 6.



Care to share your timing code? Not that I don't trust your results, but 
timings are very sensitive to the exact thing you do, and I'd like to see 
what that is.


Happy to do so -- if I made a mistake I'd like to know about it and learn.

It'll have to wait two days 'til I get back to work, though... I'll post 
it asap.


~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-03 Thread Stephen Hansen

On 2010-04-02 20:24:46 -0700, Patrick Maupin said:


On Apr 2, 10:11 pm, Stephen Hansen apt.shan...@gmail.invalid wrote:


I don't know if properties are really faster or slower then a
__getattr__, but I find them a lot cleaner if I want to delay some
calculation until needed like that.


Well, the relative speed of properties vs. __getattr__ can become
irrelevant in at least two ways:

1) If the __getattr__ only calculates the value one time and then
stuffs it into the instance dictionary, now you are really comparing
the relative speed of properties vs. lookup of an attribute in the
instance dict.  If you're at all concerned about speed, I think there
is a clear winner here.


I concede it would probably be notably faster, but there's a big 
difference between at all concerned about speed and optimizing a 
profiled bottleneck.


The speed difference between direct attribute lookup and properties may 
be notable, but that doesn't make a clear winner here. Now that I have 
(with either method) optimized the expensive value-calculation 
operation such that it only happens on-demand and once, I now have to 
weigh further optimization.


Is the difference in speed between a standard attribute lookup and a 
property fetch worth losing the clarity the property brings over the 
__getattr__ solution, especially considering the __getattr__ creates a 
fuzzy 'sometimes this code is responsible, othertimes the dict is' 
situation that someone may down the road miss in maintenance?


For me, usually not-- unless profiling pushes me to reconsider. But 
everyone makes these calls differently.



2) There is a single __getattr__ function, vs. one property for every
attribute that needs a property.  In cases where you can somehow
easily compute the attribute names as well as the attribute values,
__getattr__ can be a *lot* less code than defining dozens of
properties.


I don't really mind a lot of properties, if they're simple. Then again, 
I often prefer regular ol' attributes where possible :) However, if I'm 
doing a dispatching sort of mechanism, or a situation where the name 
isn't something static, set in stone or pre-defined-- then certainly, 
__getattr__ is a fine solution. I don't mind it where its the clearest 
way to accomplish a goal.


--
--S

... p.s: change the .invalid to .com in email address to reply privately.

--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread kj
In mailman.1437.1270163476.23598.python-l...@python.org Steve Holden 
st...@holdenweb.com writes:

But the real problem is that the OP is insisting on using purely
procedural Python when the problem is screaming for an object-oriented
answer.

My initial reaction to this comment was something like What? switch
from procedural to OO just to be able to do some one-time initialization
of function-private data???  But then, again, since Python allows
easy mixing of both programming styles, I suppose one could refactor this:

procedural
def spam(x, y, z):
try:
mongo = spam.mongo
except AttributeError:
mongo = spam.mongo = heavy_lifting_at_runtime()
return frobnicate(x, y, z, mongo)

ham = spam(3, 4, 5)
/procedural

into this:

OO
class _Spam(object):
@classmethod
def _(cls, x, y, z):
try:
mongo = cls.mongo
except AttributeError:
mongo = cls.mongo = heavy_lifting_at_runtime()
return frobnicate(x, y, z, mongo)

ham = _Spam._(1, 2, 3)
/OO


Is this really more natural or more readable?  Hmmm.

In any case, the first solution does rely on the fact that functions
are objects, and therefore can have attributes, so even the
procedural version relies on Python's OO model.

Other responses advocated for global variables.  I avoid them in
general, and doubly so in Python, because I find Python's shenanigans
with globals mystifying (this business of becoming silently local
if assigned to); it's one rare instance in which Python out-Perls
Perl.  And yes, I know that the language includes ways to deal with
this (with the global keyword, etc.) but I find the whole scheme
is so much cutting against the grain.

Thanks for all the replies.  There are a lot of good ideas there.
I'm particular, I'm thankful for the pointers to PEP 3130 (initial
reaction: maybe I should learn Dutch) and to functools.wraps, and
for the code snippets.

~K
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Paul McGuire
On Apr 1, 5:34 pm, kj no.em...@please.post wrote:
 When coding C I have often found static local variables useful for
 doing once-only run-time initializations.  For example:


Here is a decorator to make a function self-aware, giving it a this
variable that points to itself, which you could then initialize from
outside with static flags or values:

from functools import wraps

def self_aware(fn):
@wraps(fn)
def fn_(*args):
return fn(*args)
fn_.__globals__[this] = fn_
return fn_

@self_aware
def foo():
this.counter += 1
print this.counter

foo.counter = 0

foo()
foo()
foo()


Prints:

1
2
3

-- Paul
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Mel
kj wrote:

 In mailman.1437.1270163476.23598.python-l...@python.org Steve Holden
 st...@holdenweb.com writes:
 
But the real problem is that the OP is insisting on using purely
procedural Python when the problem is screaming for an object-oriented
answer.
 
 My initial reaction to this comment was something like What? switch
 from procedural to OO just to be able to do some one-time initialization
 of function-private data???

Yeah, actually.  If the subject had been Python-style object attributes in 
C? somebody might have suggested C static variables.  An example I wrote 
lately

volatile static int random_bit ()
{
static unsigned short lfsr = 0xACE1u;   // seeded LFSR 
// taps: 16 14 13 11; characteristic polynomial: x^16 + x^14 + x^13 + 
x^11 + 1
lfsr = (lfsr  1) ^ (-(lfsr  1u)  0xB400u);
return lfsr  1;
} // random_bit

(excuse is: this was written for cheap execution in an 8-bit processor.)

This does OK -- but fails the instant I decide that my program needs more 
than one pseudo-random bit stream.  Then I have the choice of writing 
several different random_bit functions, or extending random_bit to take a 
pointer to a seeded LFSR provided by the individual caller.

Refactoring the Python function to a Python class, as you mention later, 
solves the static-access problem, but that solution is just as vulnerable to 
the need-more-than-just-the-one problem as my C function.

Mel.



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Duncan Booth
kj no.em...@please.post wrote:

  I suppose one could refactor this:
 
procedural
 def spam(x, y, z):
 try:
 mongo = spam.mongo
 except AttributeError:
 mongo = spam.mongo = heavy_lifting_at_runtime()
 return frobnicate(x, y, z, mongo)
 
 ham = spam(3, 4, 5)
/procedural
 
 into this:
 
OO
 class _Spam(object):
 @classmethod
 def _(cls, x, y, z):
 try:
 mongo = cls.mongo
 except AttributeError:
 mongo = cls.mongo = heavy_lifting_at_runtime()
 return frobnicate(x, y, z, mongo)
 
 ham = _Spam._(1, 2, 3)
/OO
 
 
 Is this really more natural or more readable?  Hmmm.

No, but that's because it is needlessly obfuscated. What's with the weird _ 
method? Why use a class method? Why not just create an instance?

class Spam(object):
   mongo = None
   def __call__(self, x, y, z):
   if self.mongo is None:
   self.mongo = heavy_lifting_at_runtime()
   return frobnicate(x, y, z, self.mongo)
spam = Spam()

ham = spam(1, 2, 3)


That's natural and readable.

There's also another good reason why the class is better than the static 
variable: you can construct multiple different instances with different 
calls to 'heavy_lifting_at_runtime'. e.g. You could write a unit test where 
mongo is initialised to mock_heavy_lifting_at_runtime().
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Ethan Furman

kj wrote:

OO
class _Spam(object):
@classmethod
def _(cls, x, y, z):
try:
mongo = cls.mongo
except AttributeError:
mongo = cls.mongo = heavy_lifting_at_runtime()
return frobnicate(x, y, z, mongo)

ham = _Spam._(1, 2, 3)
/OO


Is this really more natural or more readable?  Hmmm.


For this type of situation, my preference would be:

class spam(object):
def __call__(self, x, y, z):
try:
mongo = self.mongo
except AttributeError:
mongo = self.mongo = heavy_lifting_at_runtime()
return frobnicate(x, y, z, mongo)
spam = spam()


No extra objects, out-of-place underscores, etc.

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Patrick Maupin
On Apr 2, 1:21 pm, Ethan Furman et...@stoneleaf.us wrote:
 For this type of situation, my preference would be:

 class spam(object):
      def __call__(self, x, y, z):
          try:
              mongo = self.mongo
          except AttributeError:
              mongo = self.mongo = heavy_lifting_at_runtime()
          return frobnicate(x, y, z, mongo)
 spam = spam()

 No extra objects, out-of-place underscores, etc.

 ~Ethan~

Well, I'm not a big fan of unnecessary try/except, so I would at least
change it to:

class spam(object):
 def __getattr__(self, name):
 if name != 'mongo':
 raise AttributeError
 self.mongo = heavy_lifting_at_runtime()
 return self.mongo
 def __call__(self, x, y, z):
 return frobnicate(x, y, z, self.mongo)
spam = spam()

Regards,
Pat
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Steven D'Aprano
On Fri, 02 Apr 2010 16:08:42 +, kj wrote:

 Other responses advocated for global variables.  I avoid them in
 general, 

In general this is wise, but remember that because Python globals are not 
globally global, but local to a single module, they're safer than globals 
in other languages. Still, it's better to avoid them when possible.


 and doubly so in Python, because I find Python's shenanigans
 with globals mystifying (this business of becoming silently local if
 assigned to); 

Globals don't become local when assigned to. You can shadow a global with 
a local of the same name, but the global remains untouched:

 myglobal = 42
 def test():
... myglobal = 0  # shadow the global with a new local
...
 test()
 myglobal
42

I find this behaviour perfectly natural, and desirable: it means I can 
assign to locals without worrying whether or not I'm about to stomp all 
over a global and destroy it. The alternative behaviour would be 
disastrous:

 def f(x): return x+1
... 
 def test():
... f = 'spam'
...
 test()
 f(2)  # this doesn't happen
Traceback (most recent call last):
  File stdin, line 1, in module
TypeError: 'str' object is not callable



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Ethan Furman

Patrick Maupin wrote:

On Apr 2, 1:21 pm, Ethan Furman et...@stoneleaf.us wrote:

For this type of situation, my preference would be:

class spam(object):
 def __call__(self, x, y, z):
 try:
 mongo = self.mongo
 except AttributeError:
 mongo = self.mongo = heavy_lifting_at_runtime()
 return frobnicate(x, y, z, mongo)
spam = spam()

No extra objects, out-of-place underscores, etc.

~Ethan~


Well, I'm not a big fan of unnecessary try/except, so I would at least
change it to:

class spam(object):
 def __getattr__(self, name):
 if name != 'mongo':
 raise AttributeError
 self.mongo = heavy_lifting_at_runtime()
 return self.mongo
 def __call__(self, x, y, z):
 return frobnicate(x, y, z, self.mongo)
spam = spam()

Regards,
Pat



Sounds like a personal preference issue, rather than a necessary / 
unnecessary issue -- after all, if you call that function a thousand 
times, only once is mongo not defined... clearly the exception.  ;)


~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Patrick Maupin
On Apr 2, 2:38 pm, Ethan Furman et...@stoneleaf.us wrote:
 Patrick Maupin wrote:
  On Apr 2, 1:21 pm, Ethan Furman et...@stoneleaf.us wrote:
  For this type of situation, my preference would be:

  class spam(object):
       def __call__(self, x, y, z):
           try:
               mongo = self.mongo
           except AttributeError:
               mongo = self.mongo = heavy_lifting_at_runtime()
           return frobnicate(x, y, z, mongo)
  spam = spam()

  No extra objects, out-of-place underscores, etc.

  ~Ethan~

  Well, I'm not a big fan of unnecessary try/except, so I would at least
  change it to:

  class spam(object):
       def __getattr__(self, name):
           if name != 'mongo':
               raise AttributeError
           self.mongo = heavy_lifting_at_runtime()
           return self.mongo
       def __call__(self, x, y, z):
           return frobnicate(x, y, z, self.mongo)
  spam = spam()

  Regards,
  Pat

 Sounds like a personal preference issue, rather than a necessary /
 unnecessary issue -- after all, if you call that function a thousand
 times, only once is mongo not defined... clearly the exception.  ;)

 ~Ethan~

Well, I think the whole discussion has basically been about personal
preference.  OTOH, but if you call the function a few million times,
you might find the cost of try/except to be something that you would
rather not incur -- it might become a performance issue rather than a
personal choice issue.  On the other OTHER hand, if you call the
function a few billion times, performance weighs more heavily in favor
of the closure approach rather than the object approach, since local
variable lookup is so much cheaper.

Regards,
Pat
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Ethan Furman

Patrick Maupin wrote:

[snippage]


Well, I think the whole discussion has basically been about personal
preference.  OTOH, but if you call the function a few million times,
you might find the cost of try/except to be something that you would
rather not incur -- it might become a performance issue rather than a
personal choice issue.  On the other OTHER hand, if you call the
function a few billion times, performance weighs more heavily in favor
of the closure approach rather than the object approach, since local
variable lookup is so much cheaper.


Indeed.  I was surprised to find your __getattr__ approach faster than 
the try/except approach (about 20% on my machine).  I'll have to think 
about that for future situations like this.


My main point, though, was using __call__, and not some weird _ method.  ;)

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Patrick Maupin
On Apr 2, 3:33 pm, Ethan Furman et...@stoneleaf.us wrote:
 My main point, though, was using __call__, and not some weird _ method.  ;)

Yes, __call__ is good.  In general, not naming things that don't need
to be named is good (but if you have too many of them to keep track
of, then, obviously, they need to be named, hence named tuples).

But I didn't need to address that, since you already did :-)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread kj
In xns9d4ec021dc8eaduncanbo...@127.0.0.1 Duncan Booth 
duncan.bo...@invalid.invalid writes:

class Spam(object):
   mongo = None
   def __call__(self, x, y, z):
   if self.mongo is None:
   self.mongo = heavy_lifting_at_runtime()
   return frobnicate(x, y, z, self.mongo)
spam = Spam()

ham = spam(1, 2, 3)

I really like this.  Thanks.

That's natural and readable.

From reading this thread, and the (a==b) ? 'Yes' : 'No' one, the
inescapable conclusion is that readability (like beauty) is very
much in the eye of the beholder, or, in this case, in the eye of
Guido.

~K
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Steven D'Aprano
On Fri, 02 Apr 2010 12:39:16 -0700, Patrick Maupin wrote:

 On Apr 2, 2:38 pm, Ethan Furman et...@stoneleaf.us wrote:
[...]
 Sounds like a personal preference issue, rather than a necessary /
 unnecessary issue -- after all, if you call that function a thousand
 times, only once is mongo not defined... clearly the exception.  ;)

 ~Ethan~
 
 Well, I think the whole discussion has basically been about personal
 preference.  OTOH, but if you call the function a few million times, you
 might find the cost of try/except to be something that you would rather
 not incur -- it might become a performance issue rather than a personal
 choice issue.


The cost of a try...except is *very* low -- about the same as a pass 
statement:

 from timeit import Timer
 t1 = Timer(pass, )
 t2 = Timer(try:\npass\nexcept Exception:\npass, )
 min(t2.repeat())/min(t1.repeat())
1.9227982449955801


Actually catching the exception, on the other hand, is quite expensive:

 t1 = Timer(len(''), )
 t2 = Timer(try:\nlen(0)\nexcept Exception:\npass, )
 min(t2.repeat())/min(t1.repeat())
10.598482743564809


The heuristic I use is, if I expect the try block to raise an exception 
more than about one time in ten, I change to an explicit test. In this 
case, since the exception should only be raised once, and then never 
again, I would use a try...except block.



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Patrick Maupin
On Apr 2, 6:57 pm, Steven D'Aprano st...@remove-this-
cybersource.com.au wrote:
 On Fri, 02 Apr 2010 12:39:16 -0700, Patrick Maupin wrote:
  On Apr 2, 2:38 pm, Ethan Furman et...@stoneleaf.us wrote:
 [...]
  Sounds like a personal preference issue, rather than a necessary /
  unnecessary issue -- after all, if you call that function a thousand
  times, only once is mongo not defined... clearly the exception.  ;)

  ~Ethan~

  Well, I think the whole discussion has basically been about personal
  preference.  OTOH, but if you call the function a few million times, you
  might find the cost of try/except to be something that you would rather
  not incur -- it might become a performance issue rather than a personal
  choice issue.

 The cost of a try...except is *very* low -- about the same as a pass
 statement:

Agreed.  In the example above, if frobnicate() is a null function, the
try/except adds about 5% to execution time on my machine.  If I were
really worried about execution time, I would use a closure *for this
particular example* as I mentioned elsewhere.  However, the cost of
the try/except is not zero, and when I have something I prefer looking
at (the __getattr__ doesn't clutter up the main-line execution with
conditionals for stuff that only gets used once at initialization)
that is always known to be cheaper in execution, that's what I use.  I
suppose some people might not like looking at the __getattr__, but
this is a memoization technique I use quite often, so I find it
idiomatic.

Regards,
Pat

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Terry Reedy

On 4/2/2010 6:59 PM, kj wrote:

Inxns9d4ec021dc8eaduncanbo...@127.0.0.1  Duncan 
Boothduncan.bo...@invalid.invalid  writes:


class Spam(object):
   mongo = None
   def __call__(self, x, y, z):
   if self.mongo is None:
   self.mongo = heavy_lifting_at_runtime()
   return frobnicate(x, y, z, self.mongo)


Unless one wants the intialization of mongo delayed in case spam is 
never called, it can go in __init__ instead.




spam = Spam()



ham = spam(1, 2, 3)


I really like this.  Thanks.


That's natural and readable.



From reading this thread, and the (a==b) ? 'Yes' : 'No' one, the

inescapable conclusion is that readability (like beauty) is very
much in the eye of the beholder, or, in this case, in the eye of
Guido.

~K



--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Terry Reedy

On 4/2/2010 1:28 PM, Paul McGuire wrote:

On Apr 1, 5:34 pm, kjno.em...@please.post  wrote:

When coding C I have often found static local variables useful for
doing once-only run-time initializations.  For example:



Here is a decorator to make a function self-aware, giving it a this
variable that points to itself, which you could then initialize from
outside with static flags or values:

from functools import wraps

def self_aware(fn):
 @wraps(fn)
 def fn_(*args):
 return fn(*args)
 fn_.__globals__[this] = fn_
 return fn_


In 3.1, at least, the wrapper is not needed.

def self_aware(fn):
fn.__globals__[this] = fn
return fn

Acts the same


@self_aware
def foo():
 this.counter += 1
 print this.counter

foo.counter = 0


Explicit and separate initialization is a pain. This should be in a 
closure or class.



foo()
foo()
foo()
Prints:



1
2
3


However, either way, the __globals__ attribute *is* the globals dict, 
not a copy, so one has


 this
function foo at 0x00F5F5D0

Wrapping a second function would overwrite the global binding.

Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Ethan Furman

Terry Reedy wrote:
Inxns9d4ec021dc8eaduncanbo...@127.0.0.1  Duncan 
Boothduncan.bo...@invalid.invalid  writes:



class Spam(object):
   mongo = None
   def __call__(self, x, y, z):
   if self.mongo is None:
   self.mongo = heavy_lifting_at_runtime()
   return frobnicate(x, y, z, self.mongo)



Unless one wants the intialization of mongo delayed in case spam is 
never called, it can go in __init__ instead.


As a matter of fact, I have an object that is usually not called during 
it's modules use, so I put in __getattr__.  Sped the modules load time 
back up to pert near instantaneous.  :)


~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Ethan Furman

Steven D'Aprano wrote:

On Fri, 02 Apr 2010 12:39:16 -0700, Patrick Maupin wrote:



On Apr 2, 2:38 pm, Ethan Furman et...@stoneleaf.us wrote:


[...]


Sounds like a personal preference issue, rather than a necessary /
unnecessary issue -- after all, if you call that function a thousand
times, only once is mongo not defined... clearly the exception.  ;)

~Ethan~


Well, I think the whole discussion has basically been about personal
preference.  OTOH, but if you call the function a few million times, you
might find the cost of try/except to be something that you would rather
not incur -- it might become a performance issue rather than a personal
choice issue.




The cost of a try...except is *very* low -- about the same as a pass 
statement:




from timeit import Timer
t1 = Timer(pass, )
t2 = Timer(try:\npass\nexcept Exception:\npass, )
min(t2.repeat())/min(t1.repeat())


1.9227982449955801


Actually catching the exception, on the other hand, is quite expensive:



t1 = Timer(len(''), )
t2 = Timer(try:\nlen(0)\nexcept Exception:\npass, )
min(t2.repeat())/min(t1.repeat())


10.598482743564809


The heuristic I use is, if I expect the try block to raise an exception 
more than about one time in ten, I change to an explicit test. In this 
case, since the exception should only be raised once, and then never 
again, I would use a try...except block.


That was my reasoning as well, but when I timed it for one million runs 
(so 1 instantiation, 999,999 simple calls), the __getattr__ time was .5 
seconds, the try...execpt block was .6; at ten million it was 5 and 6.


At those rates, personal preference takes over, at least for me.

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Stephen Hansen

On 2010-04-02 19:42:29 -0700, Ethan Furman said:


Terry Reedy wrote:
Inxns9d4ec021dc8eaduncanbo...@127.0.0.1  Duncan 
Boothduncan.bo...@invalid.invalid  writes:



class Spam(object):
mongo = None
def __call__(self, x, y, z):
if self.mongo is None:
self.mongo = heavy_lifting_at_runtime()
return frobnicate(x, y, z, self.mongo)



Unless one wants the intialization of mongo delayed in case spam is 
never called, it can go in __init__ instead.


As a matter of fact, I have an object that is usually not called during 
it's modules use, so I put in __getattr__.  Sped the modules load time 
back up to pert near instantaneous.  :)


~Ethan~


I prefer:

class Spam(object):
   def __init__(self):
   self._mondo = None

   def _get_mondo(self):
   if self._mondo is None:
   self._mondo = heavy_lifting_at_runtime()
   return self._mondo

   mondo = property(_get_mondo)

   def __call__(self, x, y, z):
   return frobnicate(x,y,z, self.mondo)

I don't know if properties are really faster or slower then a 
__getattr__, but I find them a lot cleaner if I want to delay some 
calculation until needed like that.


--
--S

... p.s: change the .invalid to .com in email address to reply privately.

--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-02 Thread Patrick Maupin
On Apr 2, 10:11 pm, Stephen Hansen apt.shan...@gmail.invalid wrote:

 I don't know if properties are really faster or slower then a
 __getattr__, but I find them a lot cleaner if I want to delay some
 calculation until needed like that.

Well, the relative speed of properties vs. __getattr__ can become
irrelevant in at least two ways:

1) If the __getattr__ only calculates the value one time and then
stuffs it into the instance dictionary, now you are really comparing
the relative speed of properties vs. lookup of an attribute in the
instance dict.  If you're at all concerned about speed, I think there
is a clear winner here.

2) There is a single __getattr__ function, vs. one property for every
attribute that needs a property.  In cases where you can somehow
easily compute the attribute names as well as the attribute values,
__getattr__ can be a *lot* less code than defining dozens of
properties.

But you're absolutely right that, in many cases, property is the best
way to go for readability (especially if the property is read-only and
you're using a recent enough python to use decorators).

Regards,
Pat
-- 
http://mail.python.org/mailman/listinfo/python-list


C-style static variables in Python?

2010-04-01 Thread kj


When coding C I have often found static local variables useful for
doing once-only run-time initializations.  For example:

int foo(int x, int y, int z) {

  static int first_time = TRUE;
  static Mongo *mongo;
  if (first_time) {
mongo = heavy_lifting_at_runtime();
first_time = FALSE;
  }

  return frobnicate(mongo, x, y, z);
}

In this case, the static variable mongo is initialized only once
(at most).

What I like most about this is that it obviates the need for a
global variable to hold the persistent value (I avoid globals like
the plague, especially in Python).  It also nicely encapsulates
the logic that determines whether initialization is required.

The best way I've found to achieve a similar effect in (procedural)
Python defines the function as a closure.  For example, here's a
function that keeps track of (and prints out) how many times it
has been called:

 def make_spam():
... counter = [0]
... def _():
... counter[0] += 1
... print counter[0]
... return _
... 
 spam = make_spam()
 spam()
1
 spam()
2
 spam()
3

(Too bad that one can't stick the whole def inside parentheses and
call the function right there, like one can do with JavaScript.)

Another approach would be to stuff the static values in the function's
__dict__.  This is less satisfactory than the closure approach
because the pseudo-static variable is accessible from outside
the function, but the code is arguably a little more straightforward,
and one does not end up with the now useless one-time closure-generating
function kicking around.  Here's another version of the function
above:

 def spam():
... d = spam.__dict__
... if not 's' in spam.__dict__:
... spam.s = 1 
... print spam.s
... spam.s += 1
... 
 spam()
1
 spam()
2
 spam()
3

Besides the external accessibility issue, I don't like explictly
coding the name of the function within the function.  Is there any
way to have the function access its own __dict__ without having to
explicitly code its name in its body?  E.g., is there some generic
special variable that, within a function, refers to the function
object itself?

I'm sure that there are many other ways to skin this cat, especially
if one starts definining fancy callable classes and whatnot.  But
is there a better *simple* way to achieve C-style static locals in
Python that does not require a lot of extra machinery?

TIA!

~K
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-01 Thread Chris Rebert
On Thu, Apr 1, 2010 at 3:34 PM, kj no.em...@please.post wrote:
 When coding C I have often found static local variables useful for
 doing once-only run-time initializations.
snip
 Another approach would be to stuff the static values in the function's
 __dict__.  This is less satisfactory than the closure approach
 because the pseudo-static variable is accessible from outside
 the function, but the code is arguably a little more straightforward,
 and one does not end up with the now useless one-time closure-generating
 function kicking around.  Here's another version of the function
 above:

 def spam():
 ...     d = spam.__dict__
 ...     if not 's' in spam.__dict__:
 ...         spam.s = 1
 ...     print spam.s
 ...     spam.s += 1
 ...
 spam()
 1
 spam()
 2
 spam()
 3

 Besides the external accessibility issue, I don't like explictly
 coding the name of the function within the function.  Is there any
 way to have the function access its own __dict__ without having to
 explicitly code its name in its body?  E.g., is there some generic
 special variable that, within a function, refers to the function
 object itself?

Nope. It's been proposed in that past
(http://www.python.org/dev/peps/pep-3130/), but that proposal was
rejected.

 I'm sure that there are many other ways to skin this cat, especially
 if one starts definining fancy callable classes and whatnot.  But
 is there a better *simple* way to achieve C-style static locals in
 Python that does not require a lot of extra machinery?

You can abuse the default argument value mechanism:

def spam(s_cell=[1]):
s = s_cell[0]
print s
s_cell[0] += 1

It's a bit less ugly when the value itself is mutable, which isn't the
case here with the integer.

Personally, I hate such abuse with a passion; I think a global
variable is clearest.

Cheers,
Chris
--
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-01 Thread Steve Holden
Chris Rebert wrote:
 On Thu, Apr 1, 2010 at 3:34 PM, kj no.em...@please.post wrote:
 When coding C I have often found static local variables useful for
 doing once-only run-time initializations.
 snip
 Another approach would be to stuff the static values in the function's
 __dict__.  This is less satisfactory than the closure approach
 because the pseudo-static variable is accessible from outside
 the function, but the code is arguably a little more straightforward,
 and one does not end up with the now useless one-time closure-generating
 function kicking around.  Here's another version of the function
 above:

 def spam():
 ... d = spam.__dict__
 ... if not 's' in spam.__dict__:
 ... spam.s = 1
 ... print spam.s
 ... spam.s += 1
 ...
 spam()
 1
 spam()
 2
 spam()
 3

 Besides the external accessibility issue, I don't like explictly
 coding the name of the function within the function.  Is there any
 way to have the function access its own __dict__ without having to
 explicitly code its name in its body?  E.g., is there some generic
 special variable that, within a function, refers to the function
 object itself?
 
 Nope. It's been proposed in that past
 (http://www.python.org/dev/peps/pep-3130/), but that proposal was
 rejected.
 
 I'm sure that there are many other ways to skin this cat, especially
 if one starts definining fancy callable classes and whatnot.  But
 is there a better *simple* way to achieve C-style static locals in
 Python that does not require a lot of extra machinery?
 
 You can abuse the default argument value mechanism:
 
 def spam(s_cell=[1]):
 s = s_cell[0]
 print s
 s_cell[0] += 1
 
 It's a bit less ugly when the value itself is mutable, which isn't the
 case here with the integer.
 
 Personally, I hate such abuse with a passion; I think a global
 variable is clearest.

But the real problem is that the OP is insisting on using purely
procedural Python when the problem is screaming for an object-oriented
answer.

If the function were instead a method then the instance namespace would
be the logical place to store the required data.

regards
 Steve
regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
See PyCon Talks from Atlanta 2010  http://pycon.blip.tv/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS:http://holdenweb.eventbrite.com/

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-01 Thread Terry Reedy

On 4/1/2010 6:34 PM, kj wrote:



When coding C I have often found static local variables useful for
doing once-only run-time initializations.  For example:

int foo(int x, int y, int z) {

   static int first_time = TRUE;
   static Mongo *mongo;
   if (first_time) {
 mongo = heavy_lifting_at_runtime();
 first_time = FALSE;
   }

   return frobnicate(mongo, x, y, z);


Global var or class or closure such as below (obviously untested ;=):

make_foo()
  mongo = heavy_lifting_at_runtime();
  def _(x,y,z):
return frobnicate(mongo, x, y, z)
  return _
foo = make_foo
del make_foo # to make sure it is *never* called again ;

Now you only have foo with a hard-to-access private object and no 
first_time checks when you call it.


Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-01 Thread Patrick Maupin
On Apr 1, 6:10 pm, Steve Holden st...@holdenweb.com wrote:
 Chris Rebert wrote:
  Personally, I hate such abuse with a passion; I think a global
  variable is clearest.

 But the real problem is that the OP is insisting on using purely
 procedural Python when the problem is screaming for an object-oriented
 answer.

 If the function were instead a method then the instance namespace would
 be the logical place to store the required data.

In some situations I will use either the default parameter
initialization Chris mentioned, or the closure mechanism that the OP
presented, but only on code that I am optimizing for speed (local
variable lookups, even in nested functions, being much faster than
global or instance lookups).  If it doesn't need to go fast, globals
or instance variables are the way to go.

Pat
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-01 Thread Steve Holden
Terry Reedy wrote:
 On 4/1/2010 6:34 PM, kj wrote:


 When coding C I have often found static local variables useful for
 doing once-only run-time initializations.  For example:

 int foo(int x, int y, int z) {

static int first_time = TRUE;
static Mongo *mongo;
if (first_time) {
  mongo = heavy_lifting_at_runtime();
  first_time = FALSE;
}

return frobnicate(mongo, x, y, z);
 
 Global var or class or closure such as below (obviously untested ;=):
 
 make_foo()
   mongo = heavy_lifting_at_runtime();
   def _(x,y,z):
 return frobnicate(mongo, x, y, z)
   return _
 foo = make_foo

I suspect you mean

foo = make_foo()

 del make_foo # to make sure it is *never* called again ;
 
 Now you only have foo with a hard-to-access private object and no
 first_time checks when you call it.
 
 Terry Jan Reedy
 
I don't think I'd ever want to use such an obscure technique in a
program. You might want to consider using functools.wraps to make sure
that the foo function looks right.

regards
 Steve
-- 
Steve Holden   +1 571 484 6266   +1 800 494 3119
See PyCon Talks from Atlanta 2010  http://pycon.blip.tv/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS:http://holdenweb.eventbrite.com/

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-01 Thread Alf P. Steinbach

* kj:

When coding C I have often found static local variables useful for
doing once-only run-time initializations.  For example:

int foo(int x, int y, int z) {

  static int first_time = TRUE;
  static Mongo *mongo;
  if (first_time) {
mongo = heavy_lifting_at_runtime();
first_time = FALSE;
  }

  return frobnicate(mongo, x, y, z);
}

In this case, the static variable mongo is initialized only once
(at most).

What I like most about this is that it obviates the need for a
global variable to hold the persistent value (I avoid globals like
the plague, especially in Python).  It also nicely encapsulates
the logic that determines whether initialization is required.


In C++ you just write

  int foo( int x, int y, int z )
  {
  static Mongo* const mongo = heavy_lifting_at_runtime();
  return frobnicate( mongo, x, y, z );
  }




The best way I've found to achieve a similar effect in (procedural)
Python defines the function as a closure.  For example, here's a
function that keeps track of (and prints out) how many times it
has been called:


def make_spam():

... counter = [0]
... def _():
... counter[0] += 1
... print counter[0]
... return _
... 

spam = make_spam()
spam()

1

spam()

2

spam()

3

(Too bad that one can't stick the whole def inside parentheses and
call the function right there, like one can do with JavaScript.)


Off the cuff, Py3:

class Spam:
def __init__( self ):
self._counter = 0

def __call__( self ):
self._counter += 1
print( counter )

spam = Spam()
spam()
spam()
spam()


[snip]

I'm sure that there are many other ways to skin this cat, especially
if one starts definining fancy callable classes and whatnot.


As I see it it's the closure that's fancy, and the class that's simple and 
direct.



 But
is there a better *simple* way to achieve C-style static locals in
Python that does not require a lot of extra machinery?


If you often need this functionality you might consider a general decorator that 
supplies the function with a self argument, e.g. like this:



example
#Py3

class Object: pass

def static_initialization( init_func ):
def self_aware( f ):
def wrapped( *args, **kwargs ):
return f( f, *args, **kwargs )
init_func( f )
return wrapped
o = Object()
o.body = self_aware
return o


# Example usage:

@static_initialization
def spam( self ):
self.counter = 0

@spam.body
def spam( self ):
self.counter += 1
print( self.counter )

spam()
spam()
spam()
/example


But as mentioned, a class is (at least IMHO) simpler and more direct.



Cheers  hth.,

- Alf (department of disingenious solutions)
--
http://mail.python.org/mailman/listinfo/python-list


Re: C-style static variables in Python?

2010-04-01 Thread Paul Rubin
kj no.em...@please.post writes:
 When coding C I have often found static local variables useful for
 doing once-only run-time initializations.  For example:

 int foo(int x, int y, int z) {
   static int first_time = TRUE;
   static Mongo *mongo;
   if (first_time) { ...


Here are some cheesy ways.

1. Put an attribute onto the function name:

  def foo(x, y, z):
if foo.first_time:
   foo.mongo = heavy_lifting_at_runtime()
   foo.first_time = False
...
  foo.first_time = True

2. Use a mutable keyword parameter:

   def foo(x, y, z, wrapped_mongo=[]):
  if len(wrapped_mongo) == 0:
 wrapped_mongo.append(heavy_lifting_at_runtime())
  mongo = wrapped_mongo[0]
  ...

3. Streamline the first method a little:

def foo(x, y, z):
   if len(foo.wrapped_mongo == 0):
  foo.wrapped_mongo.append(heavy_lifting_at_runtime())
   mongo = foo.wrapped_mongo[0]  
   ...
   foo.wrapped_mongo = []

All of these of course don't give as good encapsulation as one might
like.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-10-22 Thread Stephan Schulz
In article [EMAIL PROTECTED], 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.

I know I'm coming late to the discussion, but the most natural way for
me would be to simulate the function via a callable object:


class hidden(object):
   def __init__(self):
  self.static_var = 0

   def __call__(self):
  self.static_var+=1
  return self.static_var

fun_with_state = hidden()


 fun_with_state()
1
 fun_with_state()
2
 fun_with_state()
3
 fun_with_state()
4

Bye,

Stephan

-- 
-- It can be done! -
   Please email me as [EMAIL PROTECTED] (Stephan Schulz)

--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-30 Thread Alan Franzoni
kj was kind enough to say:

 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?

There've been plenty of answers, and I'm not absolutely sure about what you
want... but closures are available in Python as well and you can use them,
and by combining them through the partial module you can get a sort of
closure factory:

from functools import partial

def getfunc(expensive_call, myfunc):
val = expensive_call()

f = partial(myfunc, val)

return f



you can then do something like that:

 f = getfunc(lambda: 1, lambda x,y:x*y)
 f(2)
6





-- 
Alan Franzoni [EMAIL PROTECTED]
-
Remove .xyz from my email in order to contact me.
-
GPG Key Fingerprint:
5C77 9DC3 BD5B 3A28 E7BC 921A 0255 42AA FE06 8F3E
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-30 Thread Rhamphoryncus
On Jul 29, 2:40 pm, kj [EMAIL PROTECTED] 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.

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.
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-30 Thread 5lvqbwl02



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...

http://www.daniweb.com/code/snippet501.html

--
http://mail.python.org/mailman/listinfo/python-list


static variables in Python?

2008-07-29 Thread kj


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.
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread Larry Bates

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.currentvalue = initialvalue

def longloopingmethod(self, listtosum):
currentvalue = self.currentvalue
for v in listtosum:
currentvalue += v


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

-Larry
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread kj
In [EMAIL PROTECTED] Larry Bates [EMAIL PROTECTED] writes:

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(foo.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.
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread Colin J. Williams

kj wrote:

In [EMAIL PROTECTED] Larry Bates [EMAIL PROTECTED] writes:


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(foo.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.
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread bearophileHUGS
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
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread Ben Finney
kj [EMAIL PROTECTED] writes:

 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
--
http://mail.python.org/mailman/listinfo/python-list

Re: static variables in Python?

2008-07-29 Thread Bruce Frederiksen
On Tue, 29 Jul 2008 21:31:01 +, kj wrote:

 In [EMAIL PROTECTED] Larry Bates [EMAIL PROTECTED] writes:

 [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(foo.x);
 }

def foo():
if not hasattr(foo, 'x'): foo.x = expensive_call()
return do_stuff_with(foo.x)

or, maybe just define foo in two steps:

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

foo.x = expensive_call()
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread Russ P.
On Jul 29, 1:40 pm, kj [EMAIL PROTECTED] 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
 --
 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):
...
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread pigmartian

[EMAIL PROTECTED] 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(**kwds):

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
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread Russ P.
On Jul 29, 6:33 pm, Russ P. [EMAIL PROTECTED] wrote:
 On Jul 29, 1:40 pm, kj [EMAIL PROTECTED] 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
  --
  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.


--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread John Machin
On Jul 30, 11:57 am, Russ P. [EMAIL PROTECTED] wrote:
 On Jul 29, 6:33 pm, Russ P. [EMAIL PROTECTED] wrote:



  On Jul 29, 1:40 pm, kj [EMAIL PROTECTED] 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
   --
   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.compile(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
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread castironpi
On Jul 29, 8:38 pm, pigmartian [EMAIL PROTECTED] wrote:
 [EMAIL PROTECTED] 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(**kwds):
         
         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( )
--
http://mail.python.org/mailman/listinfo/python-list


Re: static variables in Python?

2008-07-29 Thread Daniel da Silva
This is the solution I suggest. It is fairly trivial, and works by
introducing the self.static 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.version = version

def getVersion(self):
return self.static.version
 ---

Daniel

On Tue, Jul 29, 2008 at 4:40 PM, kj [EMAIL PROTECTED] 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
 --
 NOTE: In my address everything before the first period is backwards;
 and the last period, and everything after it, should be discarded.
 --
 http://mail.python.org/mailman/listinfo/python-list

--
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-08-08 Thread Paddy

Cameron Laird wrote:
 In article [EMAIL PROTECTED],
 Paddy [EMAIL PROTECTED] wrote:
   .
   [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.static = 0
   accumulator.static += x
   return accumulator.static

   print accumulator(3)
   print accumulator(5)

Thanks Cameron, I'll accumulate this in my toolbox.

- pad.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-08-07 Thread Cameron Laird
In article [EMAIL PROTECTED],
Paddy [EMAIL PROTECTED] wrote:
.
[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.static = 0
  accumulator.static += x
  return accumulator.static
  
  print accumulator(3)
  print accumulator(5)
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-08-03 Thread Slawomir Nowaczyk
On Tue, 01 Aug 2006 07:37:20 -0400
Michael Yanowitz [EMAIL PROTECTED] wrote:

#I like the class idea, however I realize that the class object itself
# has to be global.

But no more global than your original set_bit was...

-- 
 Best wishes,
   Slawomir Nowaczyk
 ( [EMAIL PROTECTED] )

To err is human, but to really fuck things up takes a computer.

-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Static Variables in Python?

2006-08-01 Thread Michael Yanowitz


-Original Message-
From: Cliff Wells [mailto:[EMAIL PROTECTED]
Sent: Monday, July 31, 2006 4:55 PM
To: Michael Yanowitz
Cc: python-list@python.org
Subject: Re: Static Variables in Python?


On Mon, 2006-07-31 at 15:21 -0400, 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.

BTW, I'm assuming this example was contrived.  In real life, I wonder
why you'd ever want to use anything besides:

bits = [ 0 ] * 16
bits [ 4 ] = 1
print Bit Array:
print ' '.join ( bits )

Having a set_bit function seems redundant when the language syntax
directly supports what you are trying to do.

Regards,
Cliff

-- 

   Thanks everyone for your help. Yes I know it is contrived. Well it is
as over-simplified version of what I really want. And yes, I do realize
after sending it about the infinite loop in the printing. I tried too
quickly to come up with a good example without testing it first.
   I like the class idea, however I realize that the class object itself
has to be global. I will look into the decorators - something which I have
avoided until now.
   I tried creating a class, but got an error: 

# * class BitsClass *  
class BitsClass (object):
def __init__(self, num_bits):
self.bits=[]
for i in range(num_bits):
self.bits.append(0)
def set(self, bit_index, value):
self.bits[bit_index] = value
return self.bits
def get(self, bit_index):
if ((bit_index = 0) and (bit_index  len(self.bits))):
return self.bits[bit_index]
else:
return scenario_globals.ERROR_
def display(self):
i = 0
while (i  len(self.bits)):
print self.bits[i],
i += 1
print '\n',

global the_bits
the_bits = BitsClass(16)

# inside another function I have:
global the_bits
the_bits.set(index, value)

  but I get back:
Traceback (most recent call last):
   ...
  File scenario_sync.py, line 245, in get_discrete_data
the_bits.set(index, value)
AttributeError: 'DiscreteBits' object has no attribute 'set'

  There is 

  I was also disappointed, I was hoping I could use BitsClass.print()
instead of BitsClass.display().

Thanks in advance:
 Michael Yanowitz


-- 
http://mail.python.org/mailman/listinfo/python-list


RE: Static Variables in Python?

2006-08-01 Thread Cliff Wells
On Tue, 2006-08-01 at 07:37 -0400, Michael Yanowitz wrote:

 # * class BitsClass *  
 class BitsClass (object):
 def __init__(self, num_bits):
 self.bits=[]
 for i in range(num_bits):
 self.bits.append(0)
 def set(self, bit_index, value):
   self.bits[bit_index] = value
   return self.bits
 def get(self, bit_index):
 if ((bit_index = 0) and (bit_index  len(self.bits))):
 return self.bits[bit_index]
 else:
 return scenario_globals.ERROR_
 def display(self):
 i = 0
 while (i  len(self.bits)):
 print self.bits[i],
 i += 1
 print '\n',
 
 global the_bits
 the_bits = BitsClass(16)
 
 # inside another function I have:
 global the_bits
 the_bits.set(index, value)
 
   but I get back:
 Traceback (most recent call last):
...
   File scenario_sync.py, line 245, in get_discrete_data
 the_bits.set(index, value)
 AttributeError: 'DiscreteBits' object has no attribute 'set'
 
   There is 
 
   I was also disappointed, I was hoping I could use BitsClass.print()
 instead of BitsClass.display().

 class BitsClass (object):
... def __init__(self, num_bits):
... self.bits=[]
... for i in range(num_bits):
... self.bits.append(0)
... def set(self, bit_index, value):
... self.bits[bit_index] = value
... return self.bits
... def get(self, bit_index):
... if ((bit_index = 0) and (bit_index  len(self.bits))):
... return self.bits[bit_index]
... else:
... return scenario_globals.ERROR_
... def display(self):
... i = 0
... while (i  len(self.bits)):
... print self.bits[i],
... i += 1
... print '\n',
...
 the_bits = BitsClass(16)
 the_bits.set (4, 1)
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]


Works for me.  I'm not sure what 'DiscreteBits' in your error refers to.
Also, you don't need to explicitly declare global variables global.

Regards,
Cliff

-- 

-- 
http://mail.python.org/mailman/listinfo/python-list


Static Variables in Python?

2006-07-31 Thread Michael Yanowitz
  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



-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread Roel Schroeven
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_index, 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
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread tac-tics

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.

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread bearophileHUGS
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

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread Carsten Haese
On Mon, 2006-07-31 at 15:21, 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.

Python does not have static variables in the sense that C does. You can
fake it in various ways, though. If I had to do it, I'd define a
callable object instead of a function, along the lines of this:

class BitSetter(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, bit_index, bit_value):
self.bits[bit_index] = bit_value
# do something with self.bits here...
print self.bits

set_bit = BitSetter()

Now you can call set_bit(...) as if it were a function, and it'll behave
the way you want.

Hope this helps,

Carsten.


-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread John Salerno
[EMAIL PROTECTED] 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
 
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread Bruno Desthuilliers
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_index, 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.
-- 
http://mail.python.org/mailman/listinfo/python-list

Re: Static Variables in Python?

2006-07-31 Thread Cliff Wells
On Mon, 2006-07-31 at 15:21 -0400, 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'
 

Many people suggest that using a class for this is the Python idiom (and
perhaps it is), but I prefer to use a decorator for adding attributes to
functions in this case:

def attrs ( **kwds ):
''' taken from PEP 318 '''
def decorate ( f ):
for k in kwds:
setattr ( f, k, kwds [ k ] )
return f
return decorate

@attrs ( bits = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] )
def set_bit ( idx, val ):
set_bit.bits [ idx ] = int ( bool ( val ) )
print Bit Array:
for i in set_bit.bits:
print i,
print 


 set_bit ( 4, 1 )
Bit Array:
0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
 set_bit ( 5, 1 )
Bit Array:
0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0


Regards,
Cliff

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread Bruno Desthuilliers
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(str, 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()))

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread Cliff Wells
On Mon, 2006-07-31 at 13:02 -0700, Cliff Wells wrote:


 @attrs ( bits = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] )

Also, IMO, it's a bit more readable to write:

bits = [ 0 for i in range ( 16 ) ]

which avoids the necessity of counting the zeros to know how many there
are.

Regards,
Cliff


-- 

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread Cliff Wells
On Mon, 2006-07-31 at 13:37 -0700, Cliff Wells wrote:
 On Mon, 2006-07-31 at 13:02 -0700, Cliff Wells wrote:
 
 
  @attrs ( bits = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ] )
 
 Also, IMO, it's a bit more readable to write:
 
 bits = [ 0 for i in range ( 16 ) ]

Or even:

bits = [ 0 ] * 16

Just be careful to only use that style when the contents of the array
are non-mutable.  The list comp does the right thing in that case (at
risk of going on a tangent):

Right:
 bits = [ { } for i in range ( 16 ) ]
 bits
[{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}]
 bits [ 0 ][ 'a' ] = 1
 bits
[{'a': 1}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}]

Wrong:
 bits = [ {} ] * 16
 bits [ 0 ][ 'a' ] = 1
 bits
[{'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}, {'a': 1},
{'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}, {'a': 1}, {'a': 1},
{'a': 1}, {'a': 1}]



Regards,
Cliff

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread Cliff Wells
On Mon, 2006-07-31 at 15:21 -0400, 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.

BTW, I'm assuming this example was contrived.  In real life, I wonder
why you'd ever want to use anything besides:

bits = [ 0 ] * 16
bits [ 4 ] = 1
print Bit Array:
print ' '.join ( bits )

Having a set_bit function seems redundant when the language syntax
directly supports what you are trying to do.

Regards,
Cliff

-- 

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread Paddy

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__.update(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

@attributeSetter(acc = n)
def accum(i):
accum.acc+= i
return accum.acc
return accum


- Paddy

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Static Variables in Python?

2006-07-31 Thread tac-tics
 But of course:

   def fun():
   global x = 10

 SyntaxError: invalid syntax
  

global x
x = 10

Close enough ^^;

-- 
http://mail.python.org/mailman/listinfo/python-list