Re: once assigment in Python

2007-09-17 Thread Larry Bates
Lorenzo Di Gregorio wrote:
 Hello,
 
 I've been using Python for some DES simulations because we don't need
 full C speed and it's so much faster for writing models.  During
 coding I find it handy to assign a variable *unless it has been
 already assigned*: I've found that this is often referred to as once
 assigment.
 
 The best I could come up with in Python is:
 
 try:
   variable
 except NameError:
   variable = method()
 
 I wonder if sombody has a solution (trick, whatever ...) which looks
 more compact in coding.  Something like:
 
 once(variable, method)
 
 doesn't work, but it would be perfect.  Of course I can preprocess the
 Python code but an all-Python solution would be more handy.
 
 Any suggestions?
 
 Thx in advance,
 Lorenzo
 
IMHO variables like what you describe are really data not program variables. 
You might consider putting variables like these in a dictionary and then check 
to see if the keys exist before assignment:

var_dict={}

#
# See if 'varname' initialized, if not it needs to be
#
if 'varname' not in var_dict:
  var_dict[varname]=somevalue

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


Re: once assigment in Python

2007-09-17 Thread Lorenzo Di Gregorio
On 17 Sep., 16:54, Larry Bates [EMAIL PROTECTED] wrote:

 IMHO variables like what you describe are really data not program variables.
 You might consider putting variables like these in a dictionary and then check
 to see if the keys exist before assignment:

 var_dict={}

 #
 # See if 'varname' initialized, if not it needs to be
 #
 if 'varname' not in var_dict:
   var_dict[varname]=somevalue

This is a good point!

I could write something like:

instantiate('component',function)

and have instantiate() to conditionally do:

instance['component']=Module(function)

Of course this means using:

instance['component'].method()

instead of just:

component.method()

A more annoying difficulty is with the fact that, while the scope of
ordinary variables is limited (function, package), the scope of
'component' would be global (the whole instance[]): having global
names could be pretty annoying in modeling a hierarchy.  Anyway, some
scoping mechanism could be implemented over the global dictionary and
this could be a good price to pay to avoid other tricks.
Further suggestions?

Thank you!
Lorenzo

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


Re: once assigment in Python

2007-09-17 Thread Steve Holden
Lorenzo Di Gregorio wrote:
 On 17 Sep., 16:54, Larry Bates [EMAIL PROTECTED] wrote:
 IMHO variables like what you describe are really data not program variables.
 You might consider putting variables like these in a dictionary and then 
 check
 to see if the keys exist before assignment:

 var_dict={}

 #
 # See if 'varname' initialized, if not it needs to be
 #
 if 'varname' not in var_dict:
   var_dict[varname]=somevalue
 
 This is a good point!
 
 I could write something like:
 
 instantiate('component',function)
 
 and have instantiate() to conditionally do:
 
 instance['component']=Module(function)
 
 Of course this means using:
 
 instance['component'].method()
 
 instead of just:
 
 component.method()
 
Well, you could do that. Or you could define a class, with a __getattr__ 
that returns the required default value in the case where no setting had 
been made.

Then you can assign components (with their own hierarchies) to the 
attributes of your top-level design ...

 A more annoying difficulty is with the fact that, while the scope of
 ordinary variables is limited (function, package), the scope of
 'component' would be global (the whole instance[]): having global
 names could be pretty annoying in modeling a hierarchy.  Anyway, some
 scoping mechanism could be implemented over the global dictionary and
 this could be a good price to pay to avoid other tricks.
 Further suggestions?
 
It's not actually that hard to create objects that allow you to access 
their attributes using *either* attribute or indexing notation.

regards
  Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC/Ltd   http://www.holdenweb.com
Skype: holdenweb  http://del.icio.us/steve.holden

Sorry, the dog ate my .sigline

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


once assigment in Python

2007-09-14 Thread Lorenzo Di Gregorio
Hello,

I've been using Python for some DES simulations because we don't need
full C speed and it's so much faster for writing models.  During
coding I find it handy to assign a variable *unless it has been
already assigned*: I've found that this is often referred to as once
assigment.

The best I could come up with in Python is:

try:
  variable
except NameError:
  variable = method()

I wonder if sombody has a solution (trick, whatever ...) which looks
more compact in coding.  Something like:

once(variable, method)

doesn't work, but it would be perfect.  Of course I can preprocess the
Python code but an all-Python solution would be more handy.

Any suggestions?

Thx in advance,
Lorenzo

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


Re: once assigment in Python

2007-09-14 Thread Calvin Spealman
This is one of the things that I often see people trying to do in
Python, where the best solution is simply to understand how Python
works and craft the code to work with the language. The problem, in my
view, is not that you don't have a good way to do this once
assignment operation, but that you are in a position where you don't
know if a name has been assigned to or not. Yes, Python is a very
dynamic language, but that doesn't mean you should exploit this to be
so dynamic that you don't know the state of your own code at a given
point.

If you don't know that a name has been assigned to or not, there are
only a few kinds of structures that lead to such a lack of state
knowledge and all of them are avoidable. A common idiom might go along
the lines of:

if A:
B = value

Now, if A is false we might not have B defined at all, turning a
condition into an error (a raised NameError if we try to use B. What
we need to do is either find an alternative value, a default value to
assign before all this, or do everything with the value inside the if
block, and not conditionally create names.

There is no good way to do your once assignment, and that isn't an
accident. Your code is fragile if you don't know what variables you
have. Depending on the type, there are some good solutions. if the
value cannot be None or if its only numbers, for example, you can do
this:

B = B or value

Now it only changes it if B is None or 0, depending on the case. This
may or may not help you. If you use a default None, you can also just
check for that identity explicitly.

On 9/14/07, Lorenzo Di Gregorio [EMAIL PROTECTED] wrote:
 Hello,

 I've been using Python for some DES simulations because we don't need
 full C speed and it's so much faster for writing models.  During
 coding I find it handy to assign a variable *unless it has been
 already assigned*: I've found that this is often referred to as once
 assigment.

 The best I could come up with in Python is:

 try:
   variable
 except NameError:
   variable = method()

 I wonder if sombody has a solution (trick, whatever ...) which looks
 more compact in coding.  Something like:

 once(variable, method)

 doesn't work, but it would be perfect.  Of course I can preprocess the
 Python code but an all-Python solution would be more handy.

 Any suggestions?

 Thx in advance,
 Lorenzo

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



-- 
Read my blog! I depend on your acceptance of my opinion! I am interesting!
http://ironfroggy-code.blogspot.com/
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: once assigment in Python

2007-09-14 Thread Lawrence D'Oliveiro
In message [EMAIL PROTECTED], Lorenzo Di
Gregorio wrote:

 During coding I find it handy to assign a variable *unless it has been
 already assigned*: I've found that this is often referred to as once
 assigment.

Why not just assign to it once at the beginning and be done with it?
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: once assigment in Python

2007-09-14 Thread Steve Holden
Lorenzo Di Gregorio wrote:
 Hello,
 
 I've been using Python for some DES simulations because we don't need
 full C speed and it's so much faster for writing models.  During
 coding I find it handy to assign a variable *unless it has been
 already assigned*: I've found that this is often referred to as once
 assigment.
 
 The best I could come up with in Python is:
 
 try:
   variable
 except NameError:
   variable = method()
 
 I wonder if sombody has a solution (trick, whatever ...) which looks
 more compact in coding.  Something like:
 
 once(variable, method)
 
 doesn't work, but it would be perfect.  Of course I can preprocess the
 Python code but an all-Python solution would be more handy.
 
 Any suggestions?
 
Without being fatuous, I would suggest you rethink your approach to the 
problem.

Do your variables have default values? If not, what happens if the user 
does not set them and your code tries to refer to them? You seem to be 
trying to apply defaults if the user hasn't set a value, when the 
correct things to do is to apply the defaults *before the user gets a 
chance to do anything at all*. Then any changes made by the user will 
overwrite the defaults.

Even better, if its practical, is to provide your functionality as one 
or more functions, whose definitions can set default values for keyword 
arguments.

regards
  Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC/Ltd   http://www.holdenweb.com
Skype: holdenweb  http://del.icio.us/steve.holden

Sorry, the dog ate my .sigline

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


Re: once assigment in Python

2007-09-14 Thread DouhetSukd
Agree that what you are looking for may not be a good idea.  So make
sure you don't shoot yourself in the foot with it.  You should
probably look into your problem some more.

 def once(obj,attrname,value):
... if hasattr(obj,attrname):
... return
... else:
... setattr(obj,attrname,value)
...
 class Foo:
... pass
...
 foo = Foo()
 once(foo,a,1)
 foo.a
1
 once(foo,b,2)
 foo.a
1
 def m1(self):
... print i am m1
...
 def m2(self):
... print i am m2
...
 once(Foo,mx,m1)
 foo.mx()
i am m1
 once(Foo,mx,m2)
 foo.mx()
i am m1


This is very generic code, but you could make it specific to a class
and an attribute.  If so look into properties.

class Foo2:

  def _setMyAttr(self,value):
 if hasattr(self,_myAttr):
   return
 self._myAttr = value

  def _getMyAttr(self):
 if not hasattr(self,_myAttr):
return somedefaultvalue
 return self._myAttr

  myAttr = property(_getMyAttr,_setMyAttr)

Note also :  stay away from __setattr__ until you know what you are
doing and
you know when to use self.__dict__ assignments.  Painful personal
experiences for me.

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


Re: once assigment in Python

2007-09-14 Thread Peter Otten
Lorenzo Di Gregorio wrote:

 I've been using Python for some DES simulations because we don't need
 full C speed and it's so much faster for writing models.  During
 coding I find it handy to assign a variable *unless it has been
 already assigned*: I've found that this is often referred to as once
 assigment.
 
 The best I could come up with in Python is:
 
 try:
   variable
 except NameError:
   variable = method()
 
 I wonder if sombody has a solution (trick, whatever ...) which looks
 more compact in coding.  Something like:
 
 once(variable, method)
 
 doesn't work, but it would be perfect.  Of course I can preprocess the
 Python code but an all-Python solution would be more handy.
 
 Any suggestions?

You can use properties to implement lazy evaluation. Or you can rely on a
naming convention:

 class Once(object):
... def __getattr__(self, name):
... if name.startswith(_calc_):
... raise AttributeError(No method to calculate attribute 
%r % name[6:])
... value = getattr(self, _calc_ + name)()
... setattr(self, name, value)
... return value
... 
 class A(Once):
... def _calc_foo(self):
... print calculating foo
... return 42
... 
 a = A()
 a.foo
calculating foo
42
 a.foo
42
 a.bar
Traceback (most recent call last):
  File stdin, line 1, in module
  File stdin, line 5, in __getattr__
  File stdin, line 4, in __getattr__
AttributeError: No method to calculate attribute 'bar'
 a._calc_bar = lambda: bar-value
 a.bar
'bar-value'

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


Re: once assigment in Python

2007-09-14 Thread Carl Banks
On Fri, 14 Sep 2007 06:16:56 +, Lorenzo Di Gregorio wrote:

 Hello,
 
 I've been using Python for some DES simulations because we don't need
 full C speed and it's so much faster for writing models.  During coding
 I find it handy to assign a variable *unless it has been already
 assigned*: I've found that this is often referred to as once
 assigment.

I could see reasons for doing something like this at a module level or 
for attributes; such as setting default values when defaults are 
expensive to calculate.  You could, as others have said, initialize the 
variable to a trivial value and then test whether it still held the 
trivial value later, but what's the point?


 The best I could come up with in Python is:
 
 try:
   variable
 except NameError:
   variable = method()
 
 I wonder if sombody has a solution (trick, whatever ...) which looks
 more compact in coding.  Something like:
 
 once(variable, method)
 
 doesn't work, but it would be perfect.

For module level variables you can do something like this:

def once(symbol,method):
g = globals()
if symbol not in g:
g[symbol] = method() 

You'd have to pass a symbol as a string, but that's no big deal.

For local variables you're stuck with trying to catch UnboundLocalError.  
There's a way to do it by examining stack frames, but I don't really 
recommend it: it's inefficient, and the once assignment doesn't make as 
much sense for local variables.



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


Re: once assigment in Python

2007-09-14 Thread Lorenzo Di Gregorio
Thank you very much for your suggestions!
I'll try in the next days to elaborate a bit on the last two ones.

By the way, the once assignment is not that evil if you use it for
hardware modeling.
Most hardware models look like:

wire1 = function()
instance component(input=wire1,output=wire2)
result = function(wire2)

When employing Python it's pretty straightforward to translate the
instance to an object.

instance = Component(input=wire1,output=wire2)

Then you don't use instance *almost* anymore: it's an object which
gets registered with the simulator kernel and gets called by reference
and event-driven only by the simulator kernel.  We might reuse the
name for calling some administrative methods related to the instance
(e.g. for reporting) but that's a pretty safe thing to do.  Of course
all this can be done during initialization, but there are some good
reasons (see Verilog vs VHDL) why it's handy do be able to do it
*anywhere*.  The annoying problem was that every time the program flow
goes over the assignment, the object gets recreated.

Indeed Python itself is not a hardware modeling language, but I built
some infrastructure to fill what I was missing and for quickly
building up a functional prototype and testing some ideas Python is
really excellent.

Best Regards,
Lorenzo

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


Re: once assigment in Python

2007-09-14 Thread Alex Martelli
Lorenzo Di Gregorio [EMAIL PROTECTED] wrote:

 When employing Python it's pretty straightforward to translate the
 instance to an object.
 
 instance = Component(input=wire1,output=wire2)
 
 Then you don't use instance *almost* anymore: it's an object which
 gets registered with the simulator kernel and gets called by reference
 and event-driven only by the simulator kernel.  We might reuse the
 name for calling some administrative methods related to the instance
 (e.g. for reporting) but that's a pretty safe thing to do.  Of course
 all this can be done during initialization, but there are some good
 reasons (see Verilog vs VHDL) why it's handy do be able to do it
 *anywhere*.  The annoying problem was that every time the program flow
 goes over the assignment, the object gets recreated.

If you originally set, e.g.,

  instance = None

then using in your later code:

  instance = instance or Component(...)

will stop the multiple creations.  Other possibilities include using a
compound name (say an.instance where 'an' is an instance of a suitable
container class) and overriding the __new__ method of class Component so
that it will not return multiple distinct objects with identical
attributes.  Has this *plain* name ever been previously assigned to
anything at all is simply not a particularly good condition to test for
(you COULD probably write a decorator that ensures that all
uninitialized local variables of a function are instead initialized to
None, but I'd DEFINITELY advise against such black magic).


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