Movatterモバイル変換


[0]ホーム

URL:


If you want X, you know where to find it (was Re: do...until wisdom needed...)

Alex Martellialeaxit at yahoo.com
Thu Apr 19 04:15:16 EDT 2001


"Andrew Dalke" <dalke at acm.org> wrote in messagenews:9bm47r$qo2$1 at slb5.atl.mindspring.net...    [snip]> >(Is there a way in Python of finding local> >variables by name on the Python stack so that a procedure can get and> >set variables in the caller's environment?  If so, you could do it,> >but it would be pretty ugly.)>> Yes and no.  Python deliberately makes it hard.  You need> to raise an exception and look up the stack frames.  ThereIn 2.1, sys._getframe (to "be used for internal andspecialized purposes only") provides a somewhat handieralternative to the classic raise-and-look-up idiom.But I don't think this has changed what you canactually _do_ once you've got the caller's frameobject -- "see, but not touch", more or less.Consider, for example:import sysif hasattr(sys, '_getframe'):    def callerlocals():        return sys._getframe(2).f_localselse:    def callerlocals():        try: raise 'catch me'        except: return sys.exc_traceback.tb_frame.f_back.f_back.f_localsany = 'pass'def f():    x = 23    print x    g(x=24)    exec any    print x    g(y=37)    exec any    print x,ydef g(**kws):    print callerlocals()    callerlocals().update(kws)    print callerlocals()f()In both 2.0 and 2.1, this outputs:23{'x': 23}{'x': 23}23{'x': 23}{'x': 23, 'y': 37}23 37I.e., the "exec 'pass'" trick has allowed the additionof a new binding for y, but not the rebinding of xanyway.  If you comment out the exec statements, thenf's attempt to access y fails:23{'x': 23}{'x': 23}23{'x': 23}{'x': 23, 'y': 37}23Traceback (most recent call last):  File "caller.py", line 28, in ?    f()  File "caller.py", line 20, in f    print x,yNameError: global name 'y' is not definedThe dictionary object has allowed the update (sortof: it has allowed the addition of y->37, but notthe rebinding of x->23 to x->24), but the code isnot looking at that dictionary to fetch 'y' -- theoptimizer, absent an exec statement, having decidedthat 'y' is a global, not a local, variable, ithas generated bytecode to fetch a global specifically.Alex


More information about the Python-listmailing list

[8]ページ先頭

©2009-2025 Movatter.jp