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 -- http://mail.python.org/mailman/listinfo/python-list