function prototyping?

B

Burton Samograd

Hi,

Is there any way to 'prototype' functions in python, as you would in
C? Would that be what the 'global' keyword is for, or is there a more
elegant or 'pythonic' way of doing forward references?
 
D

Duncan Booth

Burton said:
Is there any way to 'prototype' functions in python, as you would in
C? Would that be what the 'global' keyword is for, or is there a more
elegant or 'pythonic' way of doing forward references?
There isn't really such a thing as a forward reference in Python. Always
remember that 'def' and 'class' are executable statements:

def a():
b()

def b():
print "b called"

a()

So long as you have executed both def statements before you call the first
function it will find the second one. In the example above, if you called
a() before executing 'def b()' the function 'b' wouldn't exist so you
couldn't call it.
 
B

Burton Samograd

Duncan Booth said:
There isn't really such a thing as a forward reference in Python. Always
remember that 'def' and 'class' are executable statements:

Ok, we'll here's what I'm trying to do. I have a dictionary that I
would like to initialize in a module file config.py:

-- config.py -------------------------
global a_fun, b_fun
dict = {
'a': a_fun,
'b': b_fun
}
--------------------------------------

where a_fun and b_fun are in fun.py:

-- fun.py ----------------------------
def a_fun(): pass
def b_fun(): pass

import config
def main():
config.dict['a']()
config.dict['b']()
main()
--------------------------------------

I like having the module/namespace seperation with the configuration
variables but I would like to make them easily (re)defined in the
configuration file by the user. Does python have the idea of a 'weak'
reference or lazy style evaluation for the definition of the dict in
the config file above so I can achive what i'm tryin to do?
 
B

bruno at modulix

Burton said:
Ok, we'll here's what I'm trying to do. I have a dictionary that I
would like to initialize in a module file config.py:

-- config.py -------------------------
global a_fun, b_fun
dict = {

dont use 'dict' as an identifier, it shadows the builtin dict type.
'a': a_fun,
'b': b_fun
}
--------------------------------------

where a_fun and b_fun are in fun.py:

-- fun.py ----------------------------
def a_fun(): pass
def b_fun(): pass

Until this point, everything is (almost) fine. You'd just need to
rewrite config.py so it imports a_fun and b_fun from fun.py:

#-- config.py -------------------------
import fun
conf = {
'a': fun.a_fun,
'b': fun.b_fun
}
# --------------------------------------

But then, we have this :
import config

And then we have a circular import...

*But* is it necessary to have the main() in the same file that defines
a_fun and b_fun ? It's quite common (and not only in Python) to use a
distinct file for the main(). So you can easily solve your problem by
splitting fun.py into fun.py and main.py:

#-- main.py -------------------------
import config
def main(*args):
config.dict['a']()
config.dict['b']()

# here we have a python trick:
if __name__ == '__main__':
import sys
sys.exit(main(*sys.argv[1:])
# --------------------------------------

I like having the module/namespace seperation with the configuration
variables but I would like to make them easily (re)defined in the
configuration file by the user.

You may want to look at one of the existing configuration modules.
Does python have the idea of a 'weak'
reference

Yes, but that's something totally different.

(snip)

HTH
 
I

infidel

If you want the user to be able to (re)define them in config.py, why
not just define them there in the first place? I may be wrong, but I
think "global" means "module level" rather than "interpreter level".
 
B

Burton Samograd

infidel said:
If you want the user to be able to (re)define them in config.py, why
not just define them there in the first place? I may be wrong, but I
think "global" means "module level" rather than "interpreter level".

That's what I'm trying to do but I'm running into problems with
the function values, since they haven't been defined yet.

I'm a C programmer, so I'm doing it in a bit of a C like way;
prototype the function, initalize the array using the prototypes, have
the functions defined somewhere else and then let the linker work it
all out for me. I was hoping that python had some sort of lazy
evaluation scheme for this type of behaviour so that you could defer
linkage (or variable evalutation) until runtime, or at least variable
reference (through the use of thunks or some sort). Maybe I was
hoping for too much :)
 
B

Burton Samograd

bruno at modulix said:
dont use 'dict' as an identifier, it shadows the builtin dict type.

just an example i jotted down, not real code.
Until this point, everything is (almost) fine. You'd just need to
rewrite config.py so it imports a_fun and b_fun from fun.py:

#-- config.py -------------------------
import fun
conf = {
'a': fun.a_fun,
'b': fun.b_fun
}
# --------------------------------------

But then, we have this :


And then we have a circular import...

*But* is it necessary to have the main() in the same file that defines
a_fun and b_fun ? It's quite common (and not only in Python) to use a
distinct file for the main(). So you can easily solve your problem by
splitting fun.py into fun.py and main.py:

ah yes, that might be a good idea. I'm just hacking together a
prototype right now and I'm thinking in C'isms still, so maybe I'll
modularize it a bit more to see if that could solve the problem.
You may want to look at one of the existing configuration modules.

I like the idea of using python as the configuration system, plus this
is giving me a good exercise with learning more of the language so I'm
going to stick with it for a bit, at least until my questions get too
annoying ;-)
Yes, but that's something totally different.

Care to describe?
 
B

bruno at modulix

Burton said:
(snip)



ah yes, that might be a good idea. I'm just hacking together a
prototype right now and I'm thinking in C'isms still,

Yeps. Python is easy to get started with, but when it comes to idioms,
it's definitively not C.

(snip)
Care to describe?

This is in the fine manual. Look for weakref.

Enjoy
 
B

bruno at modulix

Burton said:
That's what I'm trying to do but I'm running into problems with
the function values, since they haven't been defined yet.

I'm a C programmer, so I'm doing it in a bit of a C like way;
prototype the function, initalize the array using the prototypes, have
the functions defined somewhere else and then let the linker work it
all out for me. I was hoping that python had some sort of lazy
evaluation scheme for this type of behaviour so that you could defer
linkage (or variable evalutation) until runtime, or at least variable
reference (through the use of thunks or some sort). Maybe I was
hoping for too much :)

It's not a problem of "hoping for too much", but a problem of paradigm
shift. You're actually *thinking* in C, and Python is a *completely
different* language. You just can't directly transpose C idioms in
Python - nor could you transpose much Python idioms in C. So you need to
'go down a level' and consider the real problem and how to solve it the
Python way - not how to implement the C-ish solution in Python.


My 2 cents
 
P

Peter Otten

Burton said:
Duncan Booth said:
There isn't really such a thing as a forward reference in Python. Always
remember that 'def' and 'class' are executable statements:

Ok, we'll here's what I'm trying to do. I have a dictionary that I
would like to initialize in a module file config.py:

-- config.py -------------------------
global a_fun, b_fun
dict = {
'a': a_fun,
'b': b_fun
}
--------------------------------------

where a_fun and b_fun are in fun.py:

-- fun.py ----------------------------
def a_fun(): pass
def b_fun(): pass

import config
def main():
config.dict['a']()
config.dict['b']()
main()
--------------------------------------

I like having the module/namespace seperation with the configuration
variables but I would like to make them easily (re)defined in the
configuration file by the user. Does python have the idea of a 'weak'
reference or lazy style evaluation for the definition of the dict in
the config file above so I can achive what i'm tryin to do?

I'd say Python has *only* that idea, but as a practical approach the
following might be easiest:

-- config.py --
a = a_fun # As a_fun is nowhere defined, config.py cannot be
# used stand-alone and may be hard to test.
b = b_fun
def c():
print "c-fun"

-- fun.py --
def a_fun(): print "a-fun"
def b_fun(): print "b-fun"

execfile("config.py") # Think #include <config.py>

def main():
a()
b()
c()

if __name__ == "__main__":
main()

A slightly stricter variant avoids cycles by using three modules:

-- fun.py --
def a_fun(): print "a-fun"
def b_fun(): print "b-fun"

-- config.py --
import fun

a = fun.a_fun
b = fun.b_fun

-- main.py --
import config

def main():
config.a()
config.b()

if __name__ == "__main__":
main()

Thanks to the if... guard you could put the main.py code into fun.py, too,
but I suppose it's easier to understand with three files.

Peter
 
B

Burton Samograd

bruno at modulix said:
It's not a problem of "hoping for too much", but a problem of paradigm
shift. You're actually *thinking* in C, and Python is a *completely
different* language. You just can't directly transpose C idioms in
Python - nor could you transpose much Python idioms in C. So you need to
'go down a level' and consider the real problem and how to solve it the
Python way - not how to implement the C-ish solution in Python.

To be honest, I'm trying to do it in a more 'lispish' way (as in emacs
lisp) where the configuration file is written in the implementation
langugage. Just an interesting experiement really to see if it would
work. It's been a year and a half since I really used python last so
I'm just getting back up to speed with the idioms so I expect to make
a few mistakes along the way.

Thanks for the help.
 
D

Dennis Lee Bieber

Ok, we'll here's what I'm trying to do. I have a dictionary that I
would like to initialize in a module file config.py:

-- config.py -------------------------
global a_fun, b_fun

You don't understand what "global" does in Python...

It only works INSIDE a "def ....", and says that the item named
exists at the module level (ie, is not local) AND will be on the left
hand side of an assignment (right hand side will automatically look at
the module level if it doesn't find it in the local namespace).
--
 
D

Dennis Lee Bieber

To be honest, I'm trying to do it in a more 'lispish' way (as in emacs
lisp) where the configuration file is written in the implementation
langugage. Just an interesting experiement really to see if it would
work. It's been a year and a half since I really used python last so
I'm just getting back up to speed with the idioms so I expect to make
a few mistakes along the way.
One thing to take into account. Unlike most other languages where
"variable names" specify fixed addresses, and assignment changes what is
inside those addresses.... Python "variable names" are "post-it notes",
the NAME is what is moved in an assignment -- it moves to the "object"
that is associated with the right hand side. Assignment does not make a
copy of the right hand side; rather it gives the object that has the
name of the RHS an additional name.

--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top