Re: [Tutor] Passing Functions or Code as Parameters
Ed Singleton wrote: On 27/10/05, Kent Johnson [EMAIL PROTECTED] wrote: Ed Singleton wrote: Can I pass a block of code that will be executed within the function's scope? Yes, you can define a function within traverse() and pass that function to things_to_do(), but I don't know how that will help. I was thinking more of something I think I read in Ruby where you can pass a block of code to a function and it will perform the block of code at each iteration, and you can operate within the scope of the function. (I think they were actually called blocks or something). Ruby has code blocks which are passed to a function. They are widely used in Ruby. The closest equivalent in Python 2.4 is to pass a function to the other function. This has much the same capabilities as Ruby blocks but not as natural a syntax. There is a proposal to add a similar capability to Python but it has not been finalized - see PEP 343: http://www.python.org/peps/pep-0343.html Kent -- http://www.kentsjohnson.com ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Passing Functions or Code as Parameters
How can I pass a block of code to a function for it to perform within itself? For example, I wrote a small function that recurses through a directory structure but keeps a track of the depth: from path import path def traverse(directory, depth=0): thedir = path(directory) for item in thedir.files(): ## Do stuff relative to the depth for item in thedir.dirs(): traverse(item,depth+1) What I want to do is something like: from path import path def traverse(directory, depth=0, things_to_do()): thedir = path(directory) for item in thedir.files(): things_to_do(depth) for item in thedir.dirs(): traverse(item,depth+1) Is this possible? Thanks Ed ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Passing Functions or Code as Parameters
Ed Singleton wrote: How can I pass a block of code to a function for it to perform within itself? For example, I wrote a small function that recurses through a directory structure but keeps a track of the depth: What I want to do is something like: from path import path def traverse(directory, depth=0, things_to_do()): thedir = path(directory) for item in thedir.files(): things_to_do(depth) for item in thedir.dirs(): traverse(item,depth+1) Is this possible? Easy, actually! You almost have it. Functions are 'first-class objects' in Python. What that means is that a function is an object as much as a list or an integer. When you define a function, you are actually binding the function object to the name you use in the def. For example: def printer(x): ... print x ... printer function printer at 0x00A3CAF0 The name 'printer' is now bound to a function object. Functions can be bound to other names or passed as parameters to functions (or stored in lists, or...). Here is a function that takes a function as a parameter and calls the passed-in function several times: def test(fn): ... for x in [1, 2, 10]: ... fn(x) To call this function with the printer function as a parameter is just like any other function call: test(printer) 1 2 10 So in your case, just remove the excess parens in your function definition. (You have to reorder the params since keyword params have to follow non-keyword params): def traverse(directory, things_to_do, depth=0): Then define your things_to_do function (which can be called whatever you want) as a function of one argument: def do_something(depth): print depth and call traverse passing this as an argument: traverse(myDir, do_something) You also have to change the recursive call to traverse(), you must pass the things_to_do parameter: for item in thedir.dirs(): traverse(item,things_to_do,depth+1) By the way this is a very powerful capability of Python. Your usage is a good example of customizing the behaviour of a function by passing another function as a parameter. You can also build lists or dicts of dispatch functions, wrap functions to modify their behaviour, etc... Kent -- http://www.kentsjohnson.com ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Passing Functions or Code as Parameters
Ed Singleton wrote: Wow, thanks again, Kent. If my understanding of functions in Python is correct, then the do_something() function won't have access to the variables inside traverse. Is this right? Yes, that's right. Python is lexically scoped which means you have access to variables in the enclosing scopes in the actual program text, not the scope of the callers. I know I could pass them as parameters: def traverse(directory, things_to_do, depth=0): thedir = path(directory) for item in thedir.files(): things_to_do(depth, item) for item in thedir.dirs(): traverse(item, things_to_do, depth+1) But what if I don't know in advance what parameters I want to pass? You don't have very many possibilities here, maybe just pass them all? You could pass locals() to things_to_do() - locals() returns a dictionary containing all the current local variables. Then things_to_do() would take a single argument and extract the variables it wants. Why do you need this much flexibility? I would just pass thedir, item and depth to things_to_do(). Can I pass a block of code that will be executed within the function's scope? Yes, you can define a function within traverse() and pass that function to things_to_do(), but I don't know how that will help. Kent PS Please reply on list so others can participate. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor