Easy questions from a python beginner

wheres pythonmonks wherespythonmonks at gmail.com
Thu Jul 22 22:47:11 EDT 2010


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 <pavlovevidence at gmail.com> wrote:
> 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
> --
> http://mail.python.org/mailman/listinfo/python-list
>



More information about the Python-list mailing list