On Thu, 22 Jul 2010 18:34:11 -0400, wheres pythonmonks 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)
Boring and slow and stupid. It makes an interesting trick to prove it can (almost) be done, but for production use? No way. There is nothing that *needs* call-by-reference that can't be done just as effectively using a slightly different approach. This approach also has the fatal flaw that not all objects have names, or have only one name. In Python, objects are often anonymous, and the standard Python idiom for swapping works fine for them: a = [1, 2, 3, "d", 5] b = ["a", "b", "c", 4, "e"] a[3], b[3] = b[3], a[3] I expect your hack to choke and die if you try swapping anonymous objects. [snip successful test of swapping using named globals] As Carl already pointed out, this doesn't work outside of the global scope. This demonstrates an interesting lesson re testing. It's not enough to test these hacks with names in the global scope. You also need to test them with names in a local and nested scope, and in classes. [...] > Now, I want to make the above codes more "Pythonic" The way to make them more Pythonic is to avoid them like the plague. One of the differences in philosophy between Perl and Python is that Python doesn't approve of doing things just because you can. There is very little interest in or respect given to hacking Python. We're programmers, not hackers, and we look for the most simple way to do things, not the gnarliest or trickiest or least obvious way. (Any yet, as a general rule, neither does Python particular get in your way. We have a saying: we're all adults here, if you want to shoot yourself in the foot, go right ahead.) Occasionally, *very* occasionally, that makes it hard to do something that would be simple in another language. But much rarer than you might think, and a lot of popular programming idioms are work-arounds that are simply not needed in Python. E.g. call-by-reference itself was a work- around to prevent unnecessary copying of large data structures like arrays in languages like Algol and Pascal (or so I understand). When Java guys come here and start asking how to implement design patterns in Python, 9 times out of 10 the answer is "you don't need it" rather than "you can't do it". It's not quite true that we consider "hack" to be a pejorative, we're certainly true of the positive uses of the word. But as a general rule the Python community looks rather askance at anything that might be described as a hack. We're far more likely to describe something as a dirty hack than a cool, nifty or amazing hack. It's not true, as some folks say, that there is "only one way to do it" in Python. But the Python ideal is for there to be "one obvious way to do it". If there's an obvious way, why would you look for an obscure, tricky hack? You better have a good reason for not using the obvious way, because writing the code is the *smallest* part of the job. You need to test it, and debug it, and maintain it, and they're all much, much harder. > is there a way to: > > 1. Get the function's arguments from the perspective of the caller? I don't understand the question. If the caller passes arg = [1,2,3], then both the caller and the called function agree that the argument is the list [1,2,3]. Both caller and callee see the same list. It would be a pretty strange programming language where the called function saw something different from what the caller passed... > 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. No. > 3. Is there a reference on all the special variables, like __foo__? If you're talking about "magic methods" and special attributes, like obj.__len__, then you should read this: http://docs.python.org/reference/datamodel.html This may also be helpful: http://www.ironpythoninaction.com/magic-methods.html If you're talking about special globals like __name__, I don't think there are any others. __name__ is (confusingly) documented here: http://docs.python.org/library/__main__.html > 4. Is there any work on deparsing (like Perl's deparse) lambda > functions to inline algebra and get a performance gain? No. How would you do that? If I have something like this: def my_func(arg): return some_class(1, 2, 3, callback=lambda x: arg.method(x)) how would you inline that? *Where* would you inline that? Perhaps you're thinking that lambdas are commonly used like this: def my_func(args): f = lambda a, b, c: 3*a + 4*b -2*c results = [] for x in args: results.append(f(2, x, 3)) results.append(f(x, x**2, x**3) return results then, yes, that lambda could be inlined. But that's a rare and uncommon use for lambdas, and some would say unpythonic. Even if you could inline it, CPython isn't big on micro-optimizations. It's generally considered that the extra complexity and risk of bugs isn't worth the tiny performance gain. Simplicity itself is a virtue, and many optimizations tend to be anything but simple, if not dirty hacks. -- Steven -- http://mail.python.org/mailman/listinfo/python-list