How to pass a reference to the current module

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Sat Aug 4 00:56:19 EDT 2007


On Fri, 03 Aug 2007 21:06:23 -0700, James Stroud wrote:

> Its very close. However, there is the possibiltiy that main.py and 
> UserDefined1.py are the same module. In such a case I'm guessing that I 
> need to resort to the gymnastics of frame inspection I mentioned 
> earlier. 


I suggest you're falling for the anti-pattern of "Big Design Up Front",
and are overly complicating your system "just in case it's useful". Why
not just _insist_ that main.py and UserDefined1.py must be different
modules? You're the application developer, you're allowed to do that.


> The problem is when this combination of possibilities exists:
> 
>     1. main.py is named without the .py (e.g. `main`) as would be
>        the convention for "programs"), and is not a true python
>        module as a result--perhaps python has a mechanism for
>        importing such files?

I don't believe it does.


>     2. foo is defined in `main`

Maybe you should just prohibit that? Do you really want to allow users to
call arbitrary code in your main application at arbitrary times and places?

Maybe you do. Okay, it's your gun and your foot.

But in any case, it shouldn't matter. main is the program running -- it
has to be, because you can't import it from another program -- so
globals()['foo'] will work.


> Possibility two (even when it is a properly named module) sets the stage 
> for a circular import, but I believe in python this is not entirely 
> worrisome. However, the combination above makes it difficult to pass a 
> reference to the `main` namespace without some sort of introspection. 

That's what globals() is for.


> Ideally, I would prefer to not require the user to provide some mapping 
> as it detracts from the convenience of the API. For example:
> 
>     from UserDefined1 import some_function
>     def foo(): [etc.]
>     def doit(): [etc.]
>     mapping = {
>                 'foo' : foo,
>                 'doit' : doit,
>                 'some_function' : some_function
>               }
> 
> The idea would be that the above mapping would be specified in the 
> configuration file:
> 
> [foo]
> param1 = float
> param2 = 4
> 
> [option1]
> __module__ = 'UserDefined1'
> __function__ = 'doit'


I'm not sure why you need the quotation marks around the module and
function names. What else could UserDefined1 be, other than a string?


-- 
Steven.




More information about the Python-list mailing list