How to pass a reference to the current module

James Stroud jstroud at mbi.ucla.edu
Sat Aug 4 10:52:28 CEST 2007


Steven D'Aprano wrote:
> 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 idea of the module I'm writing is to allow the user to define 
functions where they want and to create single-file python scripts that 
can make use of my API. The point of the module is to be beginner 
friendly, but maybe that is asking too much as user friendliness might 
be a potentially useful but provably unnecessary attribute.

>>     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?

It would be the user's main and they would be importing my module. I 
would like my module to be aware of the contents of the user's module. I 
thought such a thing would be possible because it seems like something 
similar is happening in distutils py2app.

> 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.

On second thought this might not be horribly bad:

    FunctionUser.do_something_with(globals(), 'doit', 7)

or

    FunctionUser.do_something_with(UserDefined1.globals(), 'foo', 7)


 From a beginner-user's perspective (i.e. potential users of my module), 
it seems a little awkward, but might be more natural on the whole than 
the alternatives. However, if I had my druthers, I would rather have 
some way to pass a reference to the current module in the former case 
and have do_something_with() call globals(). I really like the idea of 
having the module or its namespace as an optional argument and 
implicitly using the calling global namespace if its left out. But 
perhaps this is bad design from an "explicit is better than implicit" 
perspective.

>> [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?

Yes, those were typos. And to be consistent, the whole listing of the 
configuration file should be (note: 'doit'->do_something_with):

[foo]
param1 = float
param2 = 4

[option1]
__module__ = UserDefined1
__function__ = do_something_with
param1 = str
param2 = 30.0

[doit]
param1 = float
param2 = float

[etc.]


With the user's main having the following in it:

    from UserDefined1 import some_function
    def foo(): [etc.]
    def doit(): [etc.]


I'm afraid my previous listing of the config file could cause confusion.

James



More information about the Python-list mailing list