Easy questions from a python beginner

Carl Banks pavlovevidence at gmail.com
Thu Jul 22 20:12:59 EDT 2010


On Jul 22, 3:34 pm, wheres pythonmonks <wherespythonmo... at 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



More information about the Python-list mailing list