the name of a module in which an instance is created?

Discussion in 'Python' started by Steven Bethard, Nov 21, 2005.

  1. The setup: I'm working within a framework (designed by someone else)
    that requires a number of module globals to be set. In most cases, my
    modules look like:
    (1) a class definition
    (2) the creation of one instance of that class
    (3) binding of the instance methods to the appropriate module globals

    I'm trying to hide the complexity of step (3) by putting it in a common
    base class. That way, when I'm writing a new module, I never have to
    see the step (3) code. Right now, that code is in the __init__ method
    of the common base class and looks something like::

    setattr(mod, 'creole_%s' % name, self._call)
    setattr(mod, 'creole_%s_Initialize' % name, self._initialize)
    setattr(mod, 'creole_%s_Finish' % name, self._finish)

    where 'mod' is the module and 'name' is the name of the module.

    In the basic situation, where the instance is created in the same module
    as the class, I can figure out 'mod' and 'name' like::

    cls = type(self)
    name = cls.__module__
    mod = __import__(cls.__module__)

    However, this fails whenever the instance is not created in the same
    module as the class was defined (e.g. when I've factored a common base
    class into another module, and only imported this class to do steps (2)
    and (3)). How can I figure out 'name' if the class was created in a
    different module?

    One option, of course, is to pass it explicitly, e.g.::

    import C
    instance = C(__name__, ...)

    This isn't a horrible option, but it does mean that I'm not hiding all
    of the step (3) machinery anymore

    Another option would be to declare a dummy class, e.g.::

    import C
    class Dummy(C):
    pass
    instance = Dummy(...)

    Again, this isn't horrible, but it also fails to hide some of the step
    (3) machinery.

    Any other possibilities?

    STeVe
    Steven Bethard, Nov 21, 2005
    #1
    1. Advertising

  2. Steven Bethard

    Mardy Guest

    Hi Steven,

    Le die Mon, 21 Nov 2005 11:37:37 -0700, Steven Bethard ha scribite:
    [...]
    > In the basic situation, where the instance is created in the same

    module
    > as the class, I can figure out 'mod' and 'name' like::
    >
    > cls = type(self)
    > name = cls.__module__
    > mod = __import__(cls.__module__)


    I'm not sure I got your problem correctly, however see if this helps:

    $ cat > test.py
    class myclass:
    name = __module__
    ^D
    $ python
    Python 2.3.5 (#2, Jun 19 2005, 13:28:00)
    [GCC 3.3.6 (Debian 1:3.3.6-6)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import test
    >>> a = test.myclass()
    >>> a.name

    'test'

    This works, as we define "name" to be a class attribute.
    Is this useful to you?


    --
    Saluti,
    Mardy
    http://interlingua.altervista.org
    Mardy, Nov 21, 2005
    #2
    1. Advertising

  3. Mardy wrote:
    > I'm not sure I got your problem correctly, however see if this helps:
    >
    > $ cat > test.py
    > class myclass:
    > name = __module__
    > ^D
    >

    [snip]
    >
    > >>> import test
    > >>> a = test.myclass()
    > >>> a.name

    > 'test'
    >
    > This works, as we define "name" to be a class attribute.
    > Is this useful to you?


    Unfortunately, no, this is basically what I currently have. Instead of
    a.name printing 'test', it should print '__main__'. I want the name of
    the module in which the *instance* is created, not the name of the
    module in which the *class* is created.

    STeVe

    P.S. Note that I already discussed two possible solutions which I didn't
    much like: (1) pass __name__ to the class instance, e.g. ``a =
    test.myclass(__name__)`` or (2) declare an empty sublcass of myclass in
    the second module (in your case, at the interactive prompt).
    Steven Bethard, Nov 22, 2005
    #3
  4. Steven Bethard <> wrote:
    ...
    > Unfortunately, no, this is basically what I currently have. Instead of
    > a.name printing 'test', it should print '__main__'. I want the name of
    > the module in which the *instance* is created, not the name of the
    > module in which the *class* is created.


    class metaSB(type):
    def __call__(cls, *a, **t):
    result = super(metaSB, cls)(*a, **t)
    result._insmodnam = sys._getframe(1).f_globals['__name__']
    return result

    and set the class's __metaclass__ to metaSB. Untested code, but the
    general idea should work.

    You could try to hack this without a custom metaclass, e.g. by trying
    sys._getframe in __init__, but that's fragile since the __init__ could
    be called by a *subclass* in whatever module...


    Alex
    Alex Martelli, Nov 23, 2005
    #4
    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. lovecreatesbeauty
    Replies:
    43
    Views:
    1,284
    Keith Thompson
    Feb 6, 2006
  2. lovecreatesbeauty
    Replies:
    2
    Views:
    575
  3. Johannes Janssen
    Replies:
    0
    Views:
    253
    Johannes Janssen
    Aug 9, 2009
  4. gentlestone
    Replies:
    6
    Views:
    922
    Bruno Desthuilliers
    Oct 6, 2009
  5. gga
    Replies:
    3
    Views:
    145
    William Morgan
    Feb 19, 2005
Loading...

Share This Page