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

S

Steven Bethard

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
 
M

Mardy

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

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

Steven Bethard

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

$ cat > test.py
class myclass:
name = __module__
^D
[snip]'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).
 
A

Alex Martelli

Steven Bethard said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top