Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'args': 0.04; '(even': 0.05; 'skip:p 60': 0.05; 'wrapper': 0.07; 'python': 0.09; "%s'": 0.09; '**kwargs)': 0.09; '**kwargs):': 0.09; 'below).': 0.09; 'func': 0.09; 'issue:': 0.09; 'skip:[ 30': 0.09; 'subject:skip:m 10': 0.09; 'wraps': 0.09; 'cc:addr:python-list': 0.10; 'def': 0.10; 'assume': 0.11; 'finished': 0.15; 'passing': 0.15; 'skip:p 40': 0.15; 'bind': 0.16; 'binding,': 0.16; 'fix:': 0.16; 'simplified': 0.16; 'to:addr:web.de': 0.16; 'wrote:': 0.17; 'parameters': 0.20; 'import': 0.21; 'cc:2**0': 0.23; 'cc:no real name:2**0': 0.24; 'pass': 0.25; 'cc:addr:python.org': 0.25; 'header:In-Reply-To:1': 0.25; 'leave': 0.26; 'message- id:@mail.gmail.com': 0.27; "doesn't": 0.28; 'fixed': 0.28; 'invoke': 0.29; 'parameters.': 0.29; 'wrap': 0.29; 'this.': 0.29; "i'm": 0.29; 'received:209.85.215.46': 0.30; 'function': 0.30; 'code': 0.31; 'print': 0.32; 'function.': 0.33; 'received:google.com': 0.34; 'list': 0.35; 'posting': 0.35; 'received:209.85': 0.35; 'created': 0.36; 'but': 0.36; 'problems': 0.36; 'subject: (': 0.36; 'possible': 0.37; 'does': 0.37; 'late': 0.37; 'received:209': 0.37; 'subject:: ': 0.38; 'nothing': 0.38; 'header:Received:5': 0.40; 'skip:u 10': 0.60; 'matter': 0.61; 'oscar': 0.84; 'otten': 0.84; 'aka': 0.91; 'write:': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=8jzPDbYAbH8L9fTWLEdm8rGwr7qm72iIdYDO+qIhfS4=; b=rli4M05WjKirGcedOCWXrMaP5ndbLq8ovULR6/C/6Ht9i9AczO5BGcy/nrbBlT5M1Q 6VDzdiqkpYHVPuZU5FXTXVmHxL9oPz1N3HktRUWu0EcTZ9CR/Xer1qCvci83RStBPrSX kLv2I8lxDwEtauiqyyORshdkIHIBXWud442KNcKmmUUI7XSCuTiY4ceA6TjY+DA/nnIW RbPgze43HTlhguVBvZtP0TRPCo2EaRu9iexI+A70tDjETBqkqKevcs0spr0YJPXXUvBu lEu8GT1aSxJwaxD1V76prEVv9P3rWTcRPGRqu8zScqyJhjBnoDEjGh+9avSJg4jR6gIu yUjQ== MIME-Version: 1.0 In-Reply-To: References: <425807738.1035823.1352809155090.JavaMail.root@sequans.com> Date: Tue, 13 Nov 2012 15:28:49 +0000 Subject: Re: Passing functions as parameter (multiprocessing) From: Oscar Benjamin To: Peter Otten <__peter__@web.de> Content-Type: text/plain; charset=ISO-8859-1 Cc: python-list@python.org X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 78 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1352820532 news.xs4all.nl 6875 [2001:888:2000:d::a6]:41008 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:33245 On 13 November 2012 12:51, Peter Otten <__peter__@web.de> wrote: > Jean-Michel Pichavant wrote: > >> I'm having problems understanding an issue with passing function as >> parameters. > >> Here's a code that triggers the issue: >> >> >> import multiprocessing >> >> def f1(): >> print 'I am f1' >> def f2(foo): >> print 'I am f2 %s' % foo >> >> workers = [ >> (f1,tuple()), >> (f2,(5,)), >> ] >> >> procs=[] >> for func, parameters in workers: > >> def subproc(*args, **kwargs): >> return func(*args, **kwargs) >> procs.append(multiprocessing.Process(target=subproc, args=parameters)) I don't know if this is to do with the way that the code was simplified before posting but this subproc function wrapper does nothing (even after Peter fixed it below). This code is needlessly complicated for what it does. > Python has late binding, and when the loop has finished the name func is > bound to f2. You have created multiple subproc functions, but that doesn't > matter as they all invoke func aka f2. > > A possible fix: > > def make_subproc(func): > def subproc(*args, **kwargs): > return func(*args, **kwargs) > return subproc > > procs=[] > for func, parameters in workers: > procs.append(multiprocessing.Process(target=make_subproc(func), > args=parameters)) The above is one way to wrap a function but it wraps the function into a function that is exactly the same as the original function. I assume that the reason for having the subproc function was to be able to bind parameters to the function like so: def make_subproc(func, args): def subproc(): return func(*args) return subproc procs=[] for func, parameters in workers: procs.append(multiprocessing.Process(target=make_subproc(func, parameters))) However, as you have already noticed, multiprocess.Process already has the machinery to do this. If you pass in a value for args you can leave out the subproc/make_subproc function and write: procs=[] for func, parameters in workers: procs.append(multiprocessing.Process(target=func, args=parameters)) A loop like this can just be a list comprehension: procs = [multiprocessing.Process(target=func, args=args) for func, args in workers] Oscar