Re: self question

2006-07-27 Thread Duncan Booth
Mike wrote:

 I think the answer is that 'def' is an executable statement in python
 rather than a definition that the compiler interprets at compile time.
 
 As a result the compiler can evaluate 'foo()' when it defines 'bar', so
 it does.
 
 The following works as expected:
 def bar():
   print foo()
 
 Hopefully somebody more knowledgable will also respond
 

The def statement is, as you say, an executable statement. It creates a new 
function object, so it is quite useful to look directly at the function 
type to see what arguments its constructor takes:

 import types
 help(types.FunctionType)
Help on class function in module __builtin__:

class function(object)
 |  function(code, globals[, name[, argdefs[, closure]]])
 |  
 |  Create a function object from a code object and a dictionary.
 |  The optional name string overrides the name from the code object.
 |  The optional argdefs tuple specifies the default argument values.
 |  The optional closure tuple supplies the bindings for free variables.
...

The arguments passed to the constructor when the def statement is executed 
are:

a code object. This object is created once when the module containing the 
function is compiled. The def doesn't have to do anything with the actual 
code, so it will take the same time whether you def a function of 1 line or 
1000 lines.

globals is the same value as you get by calling the builtin globals().

name is the function name. It's a string constant.

argdefs is the interesting one here. It is a tuple of the default argument 
values and is created every time the def statement is executed.

closure is another tuple which is created every time the def statement is 
executed. This allows a def nested inside another function to reference the 
current local variables which are in scope when the def executes. This 
tuple can only contain cell objects which are an internal object type used 
for scoped variables.

So, argdefs and closure are the two things which are different each time 
you def a function, everything else is constant and shared between 
definitions of the same function.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: self question

2006-07-26 Thread Chris Lambacher
On Tue, Jul 25, 2006 at 08:08:32PM +0200, Sch?le Daniel wrote:
 [EMAIL PROTECTED] schrieb:
  cnt = 1
  def foo():
 global cnt
 cnt += 1
 return cnt
 
  def bar(x=foo()):
 print x
 
  bar()  # 2
  bar()  # 2
  bar()  # 2
  
  Looks to me like you want to use the following programming pattern to
  get dynamic default arguments:
  
  cnt = 1
  def foo():
  global cnt
  cnt += 1
  return cnt
  
  def bar(x=None):
  if x is None:
  x = foo()
  print x
   
  bar()   # 2
  bar()   # 3
  bar()   # 4
 
 yes, I haven't thought of that
 nowI changed my class to
 
 class Graph:
   settings = {
   NumNodes : 10,
   MinNodes : 2,
   MaxNodes : 5
   }
   def randomizeEdges(self,
   lowhigh = (settings[MinNodes], settings[MaxNodes])):
Note that this is a change in behaviour from what you originally stated you
wanted.  settings is a dictionary that is shared between all instances of
Graph.  The previous poster was suggesting the correct pattern for the
behaviour you requested.  Generally if you want a parameter to have a dynamic
default argument you set the default value to None, test for None in the body
of the function/method and set the value appropriately.
   low, high = lowhigh
   for node in self.nodes:
   x = random.randint(low, high)
   # link the nodes
 
 
 maybe the only minor point is that no relationship
 can be expressed
 
 settings = {
   NumNode : 10,
   MinNode : settings[NumNode] / 2,
   MaxNode : settings[NumNode]
 }
 
 but I think the solution is nevertheless ok
 
 
 Regards, Daniel
 -- 
 http://mail.python.org/mailman/listinfo/python-list
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: self question

2006-07-26 Thread Mike

Schüle Daniel wrote:
 Hi all,

 given python description below

 import random

 class Node:
  def __init__(self):
  self.nachbarn = []

 class Graph(object):
   # more code here
  def randomizeEdges(self, low=1, high=self.n):
  pass


 graph = Graph(20)
 graph.randomizeEdges(2,5)

 I am burned by high=self.n
 quick test with

 cnt = 1
 def foo():
   global cnt
   cnt += 1
   return cnt

 def bar(x=foo()):
   print x

 bar() # 2
 bar() # 2
 bar() # 2

 this is not behaviour C++ programmer would expect
 does someone know why this kind of behaviour is/was choosen?

 Regards, Daniel

I think the answer is that 'def' is an executable statement in python
rather than a definition that the compiler interprets at compile time.

As a result the compiler can evaluate 'foo()' when it defines 'bar', so
it does.

The following works as expected:
def bar():
  print foo()

Hopefully somebody more knowledgable will also respond

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


self question

2006-07-25 Thread Schüle Daniel
Hi all,

given python description below

import random

class Node:
 def __init__(self):
 self.nachbarn = []

class Graph(object):
# more code here
 def randomizeEdges(self, low=1, high=self.n):
 pass


graph = Graph(20)
graph.randomizeEdges(2,5)

I am burned by high=self.n
quick test with

cnt = 1
def foo():
global cnt
cnt += 1
return cnt

def bar(x=foo()):
print x

bar()   # 2
bar()   # 2
bar()   # 2

this is not behaviour C++ programmer would expect
does someone know why this kind of behaviour is/was choosen?

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


Re: self question

2006-07-25 Thread dan . gass
 cnt = 1
 def foo():
   global cnt
   cnt += 1
   return cnt

 def bar(x=foo()):
   print x

 bar() # 2
 bar() # 2
 bar() # 2

Looks to me like you want to use the following programming pattern to
get dynamic default arguments:

cnt = 1
def foo():
global cnt
cnt += 1
return cnt

def bar(x=None):
if x is None:
x = foo()
print x
 
bar()   # 2
bar()   # 3
bar()   # 4

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


Re: self question

2006-07-25 Thread Schüle Daniel
[EMAIL PROTECTED] schrieb:
 cnt = 1
 def foo():
  global cnt
  cnt += 1
  return cnt

 def bar(x=foo()):
  print x

 bar()# 2
 bar()# 2
 bar()# 2
 
 Looks to me like you want to use the following programming pattern to
 get dynamic default arguments:
 
 cnt = 1
 def foo():
   global cnt
   cnt += 1
   return cnt
 
 def bar(x=None):
   if x is None:
   x = foo()
   print x
  
 bar() # 2
 bar() # 3
 bar() # 4

yes, I haven't thought of that
nowI changed my class to

class Graph:
settings = {
NumNodes : 10,
MinNodes : 2,
MaxNodes : 5
}
def randomizeEdges(self,
lowhigh = (settings[MinNodes], settings[MaxNodes])):
low, high = lowhigh
for node in self.nodes:
x = random.randint(low, high)
# link the nodes


maybe the only minor point is that no relationship
can be expressed

settings = {
NumNode : 10,
MinNode : settings[NumNode] / 2,
MaxNode : settings[NumNode]
}

but I think the solution is nevertheless ok


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


Re: self question

2006-07-25 Thread Schüle Daniel
correction :)

 class Graph:
 settings = {
 NumNodes : 10,
 MinNodes : 2,
 MaxNodes : 5
 }
 def randomizeEdges(self,
 lowhigh = (settings[MinNodes], settings[MaxNodes])):

of course this should be
  Graph.settings[MinNodes], Graph.settings[MaxNodes])
-- 
http://mail.python.org/mailman/listinfo/python-list