Get importer module from imported module

Discussion in 'Python' started by dody suria wijaya, Feb 7, 2005.

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

    > import a
    > a.How()



    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 <>, YM: dody, [36932B53]
    dody suria wijaya, Feb 7, 2005
    #1
    1. Advertising

  2. dody suria wijaya

    Duncan Booth Guest

    dody suria wijaya wrote:

    >
    > 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
    >==============
    >
    >> import a
    >> a.How()

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


    '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.
    Duncan Booth, Feb 7, 2005
    #2
    1. Advertising

  3. Re[2]: 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:

    >>
    >> 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
    >>==============
    >>
    >>> import a
    >>> a.How()

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


    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.
    dody suria wijaya, Feb 7, 2005
    #3
  4. dody suria wijaya

    Duncan Booth Guest

    Re: Re[2]: Get importer module from imported module

    dody suria wijaya wrote:

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


    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:

    > #Module c

    import sys
    food_no = sys.argv[1]
    m = __import__(food_no)
    goodie = b.Salty(m)

    > #Module b

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

    > #Module c

    import sys
    food_no = sys.argv[1]
    goodie = b.Salty(food_no)

    > #Module b

    ....
    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)
    ....
    Duncan Booth, Feb 7, 2005
    #4
  5. Re[4]: 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:

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


    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:

    >> #Module c

    DB> import sys
    DB> food_no = sys.argv[1]
    DB> m = __import__(food_no)
    DB> goodie = b.Salty(m)

    >> #Module b

    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.

    >> #Module c

    DB> import sys
    DB> food_no = sys.argv[1]
    DB> goodie = b.Salty(food_no)

    >> #Module b

    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> ...
    dody suria wijaya, Feb 8, 2005
    #5
  6. Re[5]: 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
    dody suria wijaya, Feb 8, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nebur
    Replies:
    0
    Views:
    216
    Nebur
    Mar 9, 2009
  2. w.p.
    Replies:
    0
    Views:
    768
  3. David
    Replies:
    2
    Views:
    529
    David
    Feb 11, 2010
  4. Dun Peal
    Replies:
    10
    Views:
    443
    Chris Rebert
    May 3, 2011
  5. Volker Nicolai
    Replies:
    9
    Views:
    906
    Fabian Pilkowski
    Jul 4, 2005
Loading...

Share This Page