import and package confusion

MRAB google at mrabarnett.plus.com
Thu Apr 30 10:24:25 EDT 2009


Dale Amon wrote:
> On Thu, Apr 30, 2009 at 08:32:31AM +0200, Jeroen Ruigrok van der Werven wrote:
> -On [20090430 02:21], Dale Amon (amon at vnl.com) wrote:
>>> import sys
>>> sys.path.extend (['../lib', '../bin'])
>>>
>> >from VLMLegacy.CardReader import CardReader
>>> rdr = CardReader ("../example/B767.dat","PRINTABLE")
>>>
>>> iotypes     = ["WINGTL","VLMPC","VLM4997"]
>>> for iotype in iotypes:
>>>        packagename = "VLMLegacy." + iotype + ".Conditions"
>>>        classname   =  iotype + "_Conditions"
>>>        code        = "from %s import Conditions as %s" \
>>>                       % (packagename, classname)
>>>        x           = compile (code,"foo","exec")
>>>        exec x
>>>        cls = globals()[classname]
>>>        a = cls(rdr,2)
>>>        a.test()
>> Right now your code boils down to:
>>
>> from VLMLegacy.VLM4997.Conditions import Conditions as VLM4997_Conditions
>> from VLMLegacy.VLMPC.Conditions import Conditions as VLMPC_Conditions
>> from VLMLegacy.WINGTL.Conditions import Conditions as WINGTL_Conditions
>>
>> And while you are, of course, allowed to do so, it's not the way you would
>> want to approach it in Python.
>>
>> For each subpackage/module you could add an import and __all__ to
>> __init__.py to expose Conditions and then shorten it all to:
>>
>> import VLMLegacy.VLM4997 as VLM4997
>> import VLMLegacy.VLMPC as VLMPC
>> import VLMLegacy.WINGTL as WINGTL
>>
>> So that you can do:
>>
>> a = VLM4997.Conditions(rdr, 2)
>> a.test()
> 
> If my proof of concept test code were actually all there was
> you would be correct. But what I wish to accomplish is that
> a string supplied from the command line does a run time load
> of code that is not even explicitely mentioned in the main
> body of the system.
> 
> 	myprogram --type NEWTYPE old.dat
> 
> Where NEWTYPE did not exist when the above code was written and
> distributed. Think of the following scenario. 
> 
> * Customer tells me, we have old data decks which are not
>   quite in any of the supported formats.
> 
> * I supply a new subpackage NEWTYPE with the varient code.
> 
> * They copy it into the package directory, VLMLegacy/NEWTYPE.
> 
> * They type the name of that package as a command line arg as
>   above.
> 
> * The code I wrote takes their string and dynamically binds
>   and uses the new code without changing anything else in
>   the code base.
> 
> Now I agree it is hackish. I don't really want to eval,
> I just want to import a module whose name is contained
> in a variable. I'm not unhappy with the second part where
> I use globals()[thestring] to get from a string to a 
> class object; I am indeed bothered that I have to eval
> to do the import as I have been unable so far to find
> a way to make it work dynamically. I'd be perfectly happy
> if something like this worked:
> 
> 	from VLMLegacy.CardReader import *
> 	opts, args  = p.parse_args()
>         iotype      = opts.type
>         targetname  = "Deck"
> 	packagename = "VLMLegacy." + iotype + "." targetname
> 	classname   =  iotype + "_" + targetname
> 
> 	# I only wish something like this worked...
> 	from packagename import targetname as classname
Try:

     cls = getattr(__import__(packagename), targetname)

> 
>         cls = globals()[classname]
> 
>         file = args[0]
>         rdr  = CardReader(file,opts.punchtype)
>         a = cls(rdr,2)
>         a.read()
> 
> 	<do minutes or hours of calculations>
> 
> but it doesn't. Oh, and it gets worse later. The data I'm
> reading is potentially straight off ancient Fortran decks
> with no spaces between numbers. ;-)
> 



More information about the Python-list mailing list