Is the behavior expected?
Alphones
Xiaobin.Huang at gmail.com
Wed Nov 26 23:16:29 EST 2008
On 11月27日, 上午12时07分, Peter Otten <__pete... at web.de> wrote:
> Alphones wrote:
> > On 11月26日, 下午9时28分, bearophileH... at lycos.com wrote:
> >> Alphones:
>
> >> > it is a little deferent from other script language.
>
> >> See also here:http://en.wikipedia.org/wiki/Dynamic_scope#Dynamic_scoping
>
> >> Python doesn't have such automatic closures, probably for performance
> >> reasons and/or maybe to keep its C implementation simpler (maybe other
> >> people here can give you an explanation of this, I too am curious).
>
> >> Bye,
> >> bearophile
>
> > i encountered this problem when i'm writing a program for packaging
> > files.
> > the program generates tasks according to description file.
> > and tasks are deferent from each other, and should be excuted at the
> > last of program.
>
> > i have experience on Lua and have learned about scheme and haskell, so
> > i wrote the wrong code in python.
>
> > now my solution is, using class taskCreator to create tasks and put
> > them into tasklist.
> > class taskCreator:
> > def __init__(self, proc, input, output):
> > self.proc = proc
> > self.input = input
> > self.output = output
> > def call(self):
> > return self.proc.call(self.input, self.output)
> > 'proc' is generated by procCreators, it's specified.
>
> > it looks more complex than lambda one.
>
> > is there any other simple way to implement it?
>
> Yes, you can have closures in Python (you already had one, the getFunc()
> function in your initial post).
>
> Random remarks:
>
> You don't need an explicit call() method, you can make instances callable:>>> class A:
>
> ... def __init__(self, name):
> ... self.name = name
> ... def __call__(self):
> ... print "calling", self.name
> ...>>> a = A("foo")
> >>> a()
>
> calling foo
>
> If your object has just this one method you can instead use a closure:
>
> >>> def make_a(name):
>
> ... def call():
> ... print "calling", name
> ... return call
> ...>>> a = make_a("bar")
> >>> a()
>
> calling bar
>
> This can be simplified further with some help from the library:
>
> >>> from functools import partial
> >>> def call(name):
>
> ... print "calling", name
> ...>>> a = partial(call, "baz")
> >>> a()
>
> calling baz
>
> Here is a complete example:
>
> import sys
> from functools import partial
>
> def lower(input, output):
> output.writelines(line.lower() for line in input)
>
> def prefix(input, output):
> for index_line in enumerate(input):
> output.write("%d: %s" % index_line)
>
> tasks = [partial(lower, open("tmp.py"), sys.stdout),
> partial(prefix, open("tmp.py"), sys.stdout)]
>
> for t in tasks:
> t()
>
> Peter
functools.partial is useful to my program.
i wrote
task = partial(lambda input, output, proc: proc(input,
output), archive_input.name, archive_output, proc)
self.todo.append(task)
instead of those TaskCreators.
and wrote
def __getExportor(self, name):
if not self.exportors.has_key(name):
return lambda input, ouput: False
return partial(lambda input, output, cmdline: filter( # filter
successed exit code to make list not empty, and it means success
lambda x: x == 0 or x == 36, # hack, 36 is the success
code for kzip, i hope there isn't any program use 36 as it's failed
exit code.
map(lambda l: os.system(l), self.interpret(cmdline,
input, output))), cmdline=self.exportors[name])
instead of ProcCreators.
I know it looks more obscure and not in the 'Python Style', it's just
for me to understand these discussions :P
More information about the Python-list
mailing list