Thanks for pointing out that swap (and my swap2) don't work everywhere -- is there a way to get it to work inside functions?
"No offense, but you seem like you're still tying to be a hacker. If that's what you want, fine, but generally speaking (and particularly for Python), you are going to have a better experience if you do it the language's way." None taken, but I always think that it is the language's job to express my thoughts... I don't like to think that my thoughts are somehow constrained by the language. The truth is that I don't intend to use these approaches in anything serious. However, I've been known to do some metaprogramming from time to time. In a recent application, I pass in a list of callables (lambdas) to be evaluated repeatedly. Clearly, a superior solution is to pass a single lambda that returns a list. [Less function call dispatches] However, it might be more efficient to avoid the function call overhead completely and pass-in a string which is substituted into a string code block, compiled, and executed. W On Thu, Jul 22, 2010 at 8:12 PM, Carl Banks <pavlovevide...@gmail.com> wrote: > On Jul 22, 3:34 pm, wheres pythonmonks <wherespythonmo...@gmail.com> > wrote: >> Okay -- so I promised that I would try the namespace mangling >> approach, and here's what I have come up with: >> >> Approach #1: Pass in the variables to be swapped as strings. (boring) >> >> >>> import sys >> >>> def swap(n1,n2): >> >> ... try: >> ... raise RuntimeException() >> ... except: >> ... e,b,t = sys.exc_info() >> ... ldict = t.tb_frame.f_back.f_locals >> ... t = ldict[n1]; >> ... ldict[n1] = ldict[n2] >> ... ldict[n2] = t >> ...>>> x = 'A' >> >>> y = 'B' >> >>> id(x) >> 47946650437696 >> >>> id(y) >> 47946649710192 >> >>> swap('x','y') >> >>> print id(x) >> 47946649710192 >> >>> print id(y) >> 47946650437696 >> >>> print x,y >> >> B A > > Have you tried calling this swap inside a function? I bet you > haven't. > > def test(): > x = "A" > y = "B" > swap("x","y") > print x,y > > >> Approach #2: Allow the user to pass in arbitrary objects, takes the >> id, infer what the variable in by hashing all possible objects, and >> then apply the swap operation above. >> >> >>> def swap2(o1,o2): >> >> ... try: >> ... raise RuntimeException() >> ... except: >> ... e,b,t = sys.exc_info() >> ... ldict = t.tb_frame.f_back.f_locals >> ... iddict = dict( (id(v), k ) for k,v in ldict.items() ) >> ... # print id(o1), id(o2) >> ... n1 = iddict[id(o1)] >> ... n2 = iddict[id(o2)] >> ... t = ldict[n1]; >> ... ldict[n1] = ldict[n2] >> ... ldict[n2] = t >> ... >> >> >>> print x,y >> B A >> >>> swap2(x,y) >> >>> print x,y >> A B > > Same question. > > >> Now, I want to make the above codes more "Pythonic" > > It's simply not possible (let alone Pythonic), in general, to rebind > variables in the namespace of the caller. > > You were able to do it for a very limited circumstance, when the > calling namespace was module-level. It doesn't work when the calling > namespace is a function. This is true in Python 2 and 3. > > IMO, even if it could work, the very act of rebinding variables in > another namespace is unPythonic. About the only time I've resorted to > it is some metaprogramming tasks, and even then I give the functions > that do it very explicit names, and I still feel dirty. > > >> -- is there a way to: >> >> 1. Get the function's arguments from the perspective of the caller? >> >> def f(x): >> print "caller's view of x = %s" % callersview(x) >> >> Then, f(1+2+3) would yield: >> caller's view of x = 1 + 2 + 3 > > Nope, other than inspecting the caller's frame. > >> 2. Is there a better way to loopup by id? I'm not very familiar with >> sys.exc_info, but creating the id->name hash each time seems like >> overkill. > > Looking up by id is a bad idea in general. Objects associated with an > id can be destroyed, and id be reused. So if you're storing an id, by > the time you get to it it could be a different object, or an object > that no longer exists. > > >> 3. Is there a reference on all the special variables, like __foo__? > > Python Language Reference > > >> 4. Is there any work on deparsing (like Perl's deparse) lambda >> functions to inline algebra and get a performance gain? > > psyco (q.g.) might help, not sure if it'll help much for lambdas, > though. > >> Thanks again for your input, >> >> W >> >> ( from Perl-hacker to Python Programmer ) > > No offense, but you seem like you're still tying to be a hacker. If > that's what you want, fine, but generally speaking (and particularly > for Python), you are going to have a better experience if you do it > the language's way. > > And just to throw this out there, based on your questions I think it's > possible that Ruby would fit your style better. (It lets you play > fast and loose with namespaces and code blocks and such.) > > > Carl Banks > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list