Indeed. Also there are times (Moose for example) where you want to do more than import a function as written. For example Moo and Moose create a custom function "has" at import time that is them attached to the caller's namespace.
The reason for this is that you want to fully attach the function in the space as a native method and this requires some closures to make work sanely. In short you want:
package foo;
use Moose;
has bar => (is => 'rw');
to behave identically as:
package notfoo;
use foo;
foo::has(bar => (is=>'rw'));
If you rely on the caller the second example would add a bar accessor to the caller's namespace (notfoo) rather than to foo. In short you on't want to use "has" in the Moose namespace. You want to add a custom function to the importing namespace.
As I understand it you can't do this in Python not because it is a bad idea (it is a very good idea sometimes) but rather because of limitations in the language (no multiline lambdas, which you need in order to do useful stuff with the symbol table in this regard unless there is an equivalent in terms of defining a method the calling class inside a closure in the imported package). But again, my knowledge of Perl is much better than my knowledge of Python, so I could be wrong.
When you get into this sort of metaprogramming, custom symbol table manipulations are not only helpful but downright necessary. It is what allows you to add a sophisticated MOP when such is not included in core.
Technically, you can do this with Python, but you'll have to use some dark magic to get the importing module namespace, in order to manipulate it. It'll not be pretty.
Instead, in normal Python it is the importing module that must decide who has access to its own namespace, and who must live within a separated one. It has a completely different set of costs and benefits. (I sometimes wonder if Guido used Perl as a counterexample when creating Python - its principles are almost completely opposite.)
The reason for this is that you want to fully attach the function in the space as a native method and this requires some closures to make work sanely. In short you want:
to behave identically as: If you rely on the caller the second example would add a bar accessor to the caller's namespace (notfoo) rather than to foo. In short you on't want to use "has" in the Moose namespace. You want to add a custom function to the importing namespace.As I understand it you can't do this in Python not because it is a bad idea (it is a very good idea sometimes) but rather because of limitations in the language (no multiline lambdas, which you need in order to do useful stuff with the symbol table in this regard unless there is an equivalent in terms of defining a method the calling class inside a closure in the imported package). But again, my knowledge of Perl is much better than my knowledge of Python, so I could be wrong.
When you get into this sort of metaprogramming, custom symbol table manipulations are not only helpful but downright necessary. It is what allows you to add a sophisticated MOP when such is not included in core.