[Python-ideas] name export

spir denis.spir at free.fr
Fri Apr 3 10:19:15 CEST 2009


Hello,

When I write tool modules that export useful names to client code, I usually use __all__ to select proper names. Sure, it's a potential source of identifier conflict. I have another custom __*names__ module attribute that allows the client at least to control which names are defined in the imported module:

# module M
__Mnames__ = [...]
__all__ = ["__Mnames__"] + __M_names__

Then
	from M import * ; print __Mnames__
outputs needed naming information:

	from M import * ; print __Mnames__ ; print dir()
==>
	['a', 'b', 'c']
	['__Mnames__', '__builtins__', '__doc__', '__file__', '__name__', 'a', 'b', 'c']

[Indeed, you'd have the same info with M.__all__, but I find it strange to have both "from M import *" and "import M" only to access its __all__ attribute. Also, it happens that a module name and it's main defined name are identical, like time.time.]

A complication arises when the toolset is structured as a hierarchy of modules. Then I have a top module that (oft) only serves as name interface. Each module exports a "name summary" attribute. For instance, in the case below (where M22 is an internal tool module, not to be exported):

M0
	M1
	M2
		M21
		M22

the import/export schedule would be:

# M21
__M21names__ = [...]
__all__ = ["__M21names__"] + __M21names__
# M22
__all__ = [...]
# M2
from M21 import *
from M22 import *
__M2names__ = [...] + __M21names__
__all__ = ["__M2names__"] +__M2names__
# M1
__M1names__ = [...]
__all__ = ["__M1names__"] + __M1names__
# M0
from M1 import *
from M2 import *
__M0names__ = [...] + __M1names__ + __M2names__
__all__ = ["__M0names__"] + __M0names__

Now, when I modify a module in a way that leads to change/delete/add exported names, I only need to care with this update _locally_. The update will automatically climb up the export chain. [Only a module name change remains problematic -- I'm thinking at an automatic module name lookup/update tool.]

Well, all of this looks a bit forced and rather unpythonic to me. It works fine, but I'm not satisfied. I wonder whether I'm overlooking something obvious. And if yes, what?
Or conversely, do you think there could/should be a nicer (and builtin) way of doing such things? 

Denis
------
la vita e estrany



More information about the Python-ideas mailing list