separate instances of modules

Eric Jacobs x at x.x
Wed Oct 27 22:22:31 EDT 1999


Helge Hess wrote:
> 
> Hi,
> 
> I'm thinking about some integration issues between a C environment I use
> and Python modules. It works like this, that one can extend the
> environment by writing components in Python where each component is
> assigned exactly one Python source file, that is, a module. Right now
> such a file looks like:
> 
> MyComponent.py:
> 
>   import stuff;
>   class MyComponentClass:
>      def a(self):
>            self.b = 5
> 
> When such a component is instantiated in the C environment, the source
> is imported (via Py_Import) or reloaded and then an instance of the
> MyComponentClass is made.
> 
> Since the source file contains always one such class (which doesn't need
> to inherit) I wonder whether it's somehow possible to use the source
> itself as the class. That is, I would like to write all the class stuff
> directly in the source (as functions and module variables), like this:
> 
>    import stuff;
>    b = 3;
>    def a():
>      b = 5;

Two things you could change in that model. First, in order for
the function to be a method of a class, it would need to take at least
one argument (the self argument), even if you never end up using that
argument. The second problem is that the assignment b = 5 refers to
a variable local to the function, and not the instance. The easiest
way to rewrite this is using the familiar self.var syntax:

    import stuff;
    b = 3;
    def a(self):
      self.b = 5;

That's pretty easy to do, if you don't mind the newmodule: (call
the above test.py)

Python 1.5.1 (#0, Apr 13 1998, 20:22:04) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import test
>>> import new
>>> c = new.classobj("classname", (), test.__dict__)
>>> x = c()
>>> x.b
3
>>> x.a()
>>> x.b
5
>>>

But you may be thinking of using global variables as actual
instance variables, as in

    import stuff;
    b = 3;
    def a():
      global b
      b = 5;

The problem is that global variables come out of a dictionary
that's a property of function objects (func_globals), and not
from instances that happen to include those functions. So in
order to emulate that effect, you're going to have to create
new function objects with the instance dictionary as their
func_globals.

Still interested? This is a serious hack. I don't recommend
it. It will bypass the class wrapper and set func_globals
manually. It will also eliminate the need to have a self
argument.

Python 1.5.1 (#0, Apr 13 1998, 20:22:04) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import test, new, types
>>> c = new.classobj("classname", (), test.__dict__)
>>> def fixfuncglobals(s, c):
...     for k, v in c.__dict__.items():
...             if type(v) != types.FunctionType:
...                     continue
...             s.__dict__[k] = new.function(v.func_code, s.__dict__, 
...			v.func_name, (v.func_defaults or ()))
...
>>> x = c()
>>> fixfuncglobals(x, c)
>>> y = c()
>>> fixfuncglobals(y, c)
>>> x.b
3
>>> y.b
3
>>> x.a()
>>> x.b
5
>>> y.b
3
>>> y.a()
>>> x.b
5
>>> y.b
5
>>> x.a
<function a at 7941b0>

^ Notice how Python considers the methods to be normal functions
rather than methods. This is because I assigned the new function
objects directly to the instance object rather than the class
object. It eliminates the need for the self argument.

You could wrap up the fixfuncglobals function into the class
constructor using a metaclass or a C extension.




More information about the Python-list mailing list