Get importer module from imported module | | |
I found this problem when trying to split a module into two.
Here's an example:
==============
#Module a (a.py):
from b import *
class Main: pass
==============
==============
#Module b (b.py)
def How():
Main_instance = module_a.Main()
return Main_instance
==============
[color=blue]
> import a
> a.How()[/color]
the problem would show at How() function. I have been unable
to get variable pointing to module a from inside module b.
In short, I need to have a variable pointing to the module
whose importing me.
--
dody s wijaya <dodysw@gmail.com>, YM: dody, [36932B53] | | | | re: Get importer module from imported module
dody suria wijaya wrote:
[color=blue]
>
> I found this problem when trying to split a module into two.
> Here's an example:
>
>==============
> #Module a (a.py):
> from b import *
> class Main: pass
>==============
>
>==============
> #Module b (b.py)
> def How():
> Main_instance = module_a.Main()
> return Main_instance
>==============
>[color=green]
>> import a
>> a.How()[/color]
>
>
> the problem would show at How() function. I have been unable
> to get variable pointing to module a from inside module b.
> In short, I need to have a variable pointing to the module
> whose importing me.
>
>[/color]
'import a' will let you reference module 'a', unless 'a' was invoked as a
script in which case you would need 'import __main__'.
#Module b (b.py)
import a
def How():
Main_instance = a.Main()
return Main_instance
But: keep in mind that all statements (except 'global') are executable in
Python, so you must not call How() until after the Main class has actually
been created. This is one reason why it is generally safer to import a
module and do the lookup when you need it instead of using 'from
amodule import *' which can only get at the names which exist at the time
it is executed.
A better solution would be to structure your code so that your modules
don't have any mutual dependencies. If your function 'How()' is in module b
then just call 'b.How()' wherever you use it and lose the import of 'b'
from 'a' altogether. | | | | re: Get importer module from imported module
Thank you for such a quick reply. There were some details I
had left behind related to my case that I guess would now
need to be told to better illustrate the problem.
I have many different module of "a", let's called it a1, a2 ...
a100, and there is only one module "b". Here's a better
example (and using some of your tips):
#Module a1
import b
class Main(b.Basic): pass
#Module a2
import b
class Main(b.Basic): pass
#Module a3
import b
class Main(b.Basic): pass
..
..
..
#Module b
class Basic: pass
class SaltyMixIn: pass
class SugaryMixIn: pass
def Salty():
class Food(SaltyMixIn,module_importing_me.Main): pass
return Food()
def Sweet():
class Food(SugaryMixIn,module_importing_me.Main): pass
return Food()
#Module c
import sys
food_no = sys.argv[1]
m = __import__(food_no)
goodie = m.Salty()
"import a" inside b would not solve the problem, since there
are many "module a" and module b does not know beforehand
which module had imported it. I could, say, put these
additional lines on all "module a" (which I previously had
and worked):
#Module a1
import b
class Main(b.Basic): pass
class Salty(SaltyMixIn,Main): pass # new
class Sweet(SaltyMixIn,Main): pass # new
but dislike it for personal taste; code dupes (there could
be a lot of food flavouring), and sheer messiness.
--
dody suria wijaya
YahooMsgr ID: dody
Monday, February 7, 2005, 6:10:14 PM, you wrote:
DB> dody suria wijaya wrote:
[color=blue][color=green]
>>
>> I found this problem when trying to split a module into two.
>> Here's an example:
>>
>>==============
>> #Module a (a.py):
>> from b import *
>> class Main: pass
>>==============
>>
>>==============
>> #Module b (b.py)
>> def How():
>> Main_instance = module_a.Main()
>> return Main_instance
>>==============
>>[color=darkred]
>>> import a
>>> a.How()[/color]
>>
>>
>> the problem would show at How() function. I have been unable
>> to get variable pointing to module a from inside module b.
>> In short, I need to have a variable pointing to the module
>> whose importing me.
>>
>>[/color][/color]
DB> 'import a' will let you reference module 'a',
DB> unless 'a' was invoked as a
DB> script in which case you would need 'import __main__'.
DB> #Module b (b.py)
DB> import a
DB> def How():
DB> Main_instance = a.Main()
DB> return Main_instance
DB> But: keep in mind that all statements (except
DB> 'global') are executable in
DB> Python, so you must not call How() until after the Main class has actually
DB> been created. This is one reason why it is
DB> generally safer to import a
DB> module and do the lookup when you need it instead of using 'from
DB> amodule import *' which can only get at the names which exist at the time
DB> it is executed.
DB> A better solution would be to structure your code so that your modules
DB> don't have any mutual dependencies. If your
DB> function 'How()' is in module b
DB> then just call 'b.How()' wherever you use it and lose the import of 'b'
DB> from 'a' altogether. | | | | re: Get importer module from imported module
dody suria wijaya wrote:
[color=blue]
> "import a" inside b would not solve the problem, since there
> are many "module a" and module b does not know beforehand
> which module had imported it.[/color]
Ok, I understand now what you are trying to achieve, but there isn't any
concept relating a module back to the first module which tried to import
it. Instead you'll have to specify the relationship yourself.
How about this:
[color=blue]
> #Module c[/color]
import sys
food_no = sys.argv[1]
m = __import__(food_no)
goodie = b.Salty(m)
[color=blue]
> #Module b[/color]
....
def Salty(module):
class Food(SaltyMixIn,module.Main): pass
return Food()
....
In fact, it looks like the importing isn't really something module c should
be concerned about. I haven't tested the following code (so it will have
bugs), but it should give you some ideas. It remembers classes it has
created so as not to duplicate them, and it also gives each class a
sensible name.
[color=blue]
> #Module c[/color]
import sys
food_no = sys.argv[1]
goodie = b.Salty(food_no)
[color=blue]
> #Module b[/color]
....
import new
Classes = {}
def makeFood(classname, food, mixin):
m = __import__(food)
main = m.Main
if (mixin, main) in Classes:
return Classes[mixin, main]()
newclass = new.classobj(classname + '_' + food, (mixin, main), {})
Classes[mixin, main] = newclass
return newclass
def Salty(food):
return makeFood('Salty', food, SaltyMixIn)
.... | | | | re: Get importer module from imported module
Yup, Got it.
New problem though. On line:
newclass = new.classobj(classname + '_' + food, (mixin, main), {})
received "TypeError: metaclass conflict: the metaclass of a
derived class must be a (non-strict) subclass of the
metaclasses of all its bases". This had not happened when
was written using 'normal' style like:
class (SaltyMixIn, Main): pass
--
dody suria wijaya
YahooMsgr ID: dody
Monday, February 7, 2005, 7:20:14 PM, you wrote:
DB> dody suria wijaya wrote:
[color=blue][color=green]
>> "import a" inside b would not solve the problem, since there
>> are many "module a" and module b does not know beforehand
>> which module had imported it.[/color][/color]
DB> Ok, I understand now what you are trying to
DB> achieve, but there isn't any
DB> concept relating a module back to the first module which tried to import
DB> it. Instead you'll have to specify the relationship yourself.
DB> How about this:
[color=blue][color=green]
>> #Module c[/color][/color]
DB> import sys
DB> food_no = sys.argv[1]
DB> m = __import__(food_no)
DB> goodie = b.Salty(m)
[color=blue][color=green]
>> #Module b[/color][/color]
DB> ...
DB> def Salty(module):
DB> class Food(SaltyMixIn,module.Main): pass
DB> return Food()
DB> ...
DB> In fact, it looks like the importing isn't really
DB> something module c should
DB> be concerned about. I haven't tested the following code (so it will have
DB> bugs), but it should give you some ideas. It remembers classes it has
DB> created so as not to duplicate them, and it also gives each class a
DB> sensible name.
[color=blue][color=green]
>> #Module c[/color][/color]
DB> import sys
DB> food_no = sys.argv[1]
DB> goodie = b.Salty(food_no)
[color=blue][color=green]
>> #Module b[/color][/color]
DB> ...
DB> import new
DB> Classes = {}
DB> def makeFood(classname, food, mixin):
DB> m = __import__(food)
DB> main = m.Main
DB> if (mixin, main) in Classes:
DB> return Classes[mixin, main]()
DB> newclass = new.classobj(classname + '_' + food, (mixin, main), {})
DB> Classes[mixin, main] = newclass
DB> return newclass
DB> def Salty(food):
DB> return makeFood('Salty', food, SaltyMixIn)
DB> ... | | | | re: Get importer module from imported module
dsw> New problem though. On line:
dsw> newclass = new.classobj(classname + '_' + food, (mixin, main), {})
dsw> received "TypeError: metaclass conflict: the metaclass of a
dsw> derived class must be a (non-strict) subclass of the
dsw> metaclasses of all its bases".
Oops, goofed up on me. The above "main" had mistakenly
pointed to the module. main.Main did the trick.
-- dsw |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,471 network members.
|