Re: self question
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
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
Re: self question
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
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
Re: self question
[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
> 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