Build classes/packages dinamicaly

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Paulo Pinto

    Build classes/packages dinamicaly

    Hi,


    I have a package that generates classes from a
    set of XML files using exec.

    So far the classes appear in the global namespace.

    Is there any way to also create packages dinamicaly
    and add the classes to those packages?

    Thanks in advance,
    Paulo Pinto

  • Peter Otten

    #2
    Re: Build classes/packages dinamicaly

    Paulo Pinto wrote:
    [color=blue]
    > I have a package that generates classes from a
    > set of XML files using exec.
    >
    > So far the classes appear in the global namespace.
    >
    > Is there any way to also create packages dinamicaly
    > and add the classes to those packages?
    >
    > Thanks in advance,
    > Paulo Pinto[/color]
    [color=blue][color=green][color=darkred]
    >>> import types
    >>> mymodule = types.ModuleTyp e("mymodule")
    >>> exec "def demo():\n\tprin t 'hello from', __name__\n" in[/color][/color][/color]
    mymodule.__dict __[color=blue][color=green][color=darkred]
    >>> mymodule.demo()[/color][/color][/color]
    hello from mymodule[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]

    Seems to work. I haven't used it myself, though.

    Peter

    Comment

    • Michele Simionato

      #3
      Re: Build classes/packages dinamicaly

      Paulo Pinto <paulo.pinto@ce rn.ch> wrote in message news:<brkkf7$jq g$1@sunnews.cer n.ch>...[color=blue]
      > Hi,
      >
      >
      > I have a package that generates classes from a
      > set of XML files using exec.
      >
      > So far the classes appear in the global namespace.
      >
      > Is there any way to also create packages dinamicaly
      > and add the classes to those packages?
      >
      > Thanks in advance,
      > Paulo Pinto[/color]

      By packages I think you mean modules. Here is a solution in Python 2.3:
      [color=blue][color=green][color=darkred]
      >>> from types import ModuleType
      >>> mymodule=Module Type("mymodule" )
      >>> print mymodule[/color][/color][/color]
      <module 'mymodule' (built-in)>[color=blue][color=green][color=darkred]
      >>> class C(object): pass[/color][/color][/color]
      ....[color=blue][color=green][color=darkred]
      >>> mymodule.C=C[/color][/color][/color]

      In older Python versions, look for the module "new".

      Comment

      • Paulo Pinto

        #4
        Re: Build classes/packages dinamicaly

        Thanks it is want I was looking for.
        However I still have a problem.

        I want to make the module available to the
        caller as if he did an import.

        For example, if I make the following call

        some_module.gen erate_module('d ummy')

        Where some_module is the module that generates
        modules dinamicaly, and dummy is the name of the
        new module.

        I would like to be able to do

        dummy.something ()

        after that call.

        I've discovered that if I do something like this

        globals()['dummy'] = module_instance _returned_by_ne w.module()


        It works, but it must be done at the same level I want to
        call dummy.something () and not from inside some_module. Because
        if I do it inside the module, globals() will be refering to the
        module globals and not to parent scope.

        Basically I would like to import the generated module to the
        module that is invoking generate_module () like an uplevel in
        Tcl.

        Is this possible?

        Cheers,
        Paulo Pinto

        Peter Otten wrote:[color=blue]
        > Paulo Pinto wrote:
        >
        >[color=green]
        >>I have a package that generates classes from a
        >>set of XML files using exec.
        >>
        >>So far the classes appear in the global namespace.
        >>
        >>Is there any way to also create packages dinamicaly
        >>and add the classes to those packages?
        >>
        >>Thanks in advance,
        >>Paulo Pinto[/color]
        >
        >[color=green][color=darkred]
        >>>>import types
        >>>>mymodule = types.ModuleTyp e("mymodule")
        >>>>exec "def demo():\n\tprin t 'hello from', __name__\n" in[/color][/color]
        >
        > mymodule.__dict __
        >[color=green][color=darkred]
        >>>>mymodule.de mo()[/color][/color]
        >
        > hello from mymodule
        >
        >
        > Seems to work. I haven't used it myself, though.
        >
        > Peter
        >[/color]

        Comment

        • Peter Otten

          #5
          Re: Build classes/packages dinamicaly

          Paulo Pinto wrote:
          [color=blue]
          > Thanks it is want I was looking for.
          > However I still have a problem.
          >
          > I want to make the module available to the
          > caller as if he did an import.
          >
          > For example, if I make the following call
          >
          > some_module.gen erate_module('d ummy')
          >
          > Where some_module is the module that generates
          > modules dinamicaly, and dummy is the name of the
          > new module.
          >
          > I would like to be able to do
          >
          > dummy.something ()
          >
          > after that call.
          >
          > I've discovered that if I do something like this
          >
          > globals()['dummy'] = module_instance _returned_by_ne w.module()
          >
          >
          > It works, but it must be done at the same level I want to
          > call dummy.something () and not from inside some_module. Because
          > if I do it inside the module, globals() will be refering to the
          > module globals and not to parent scope.
          >
          > Basically I would like to import the generated module to the
          > module that is invoking generate_module () like an uplevel in
          > Tcl.
          >
          > Is this possible?[/color]

          Don't know, but rebinding in the calling scope from inside a function call
          looks like fighting the language to me. Maybe redefining __import__() would
          be better:

          <myimport.py>
          import __builtin__
          import types, sys

          originalimport = __builtin__.__i mport__

          def myimport(name, *args):
          print "importing" , name
          try:
          return originalimport( name, *args)
          except ImportError:
          print "generating ", name
          module = types.ModuleTyp e(name)
          exec "def demo(*args):\n\ tprint 'demo%r' % (args,)\n" in
          module.__dict__
          sys.modules[name] = module # put it into the cache
          return module

          __builtin__.__i mport__ = myimport
          </myimport.py>

          I simply generate any module that cannot successfully be imported, but you
          could change this to meet your needs. Now a usage example:

          <usemyimport.py >
          import myimport # put it first, because it messes with the built-ins

          print "first import"
          import os
          import generated
          print
          print "second import"
          import os, generated

          generated.demo( "hi", "there")
          </usemyimport.py>

          However, this is just a smoother variant of the

          module = generate("modul ename")

          pattern.

          Peter

          Comment

          • vincent wehren

            #6
            Re: Build classes/packages dinamicaly


            "Paulo Pinto" <paulo.pinto@ce rn.ch> schrieb im Newsbeitrag
            news:brmpt2$7nn $1@sunnews.cern .ch...
            | Thanks it is want I was looking for.
            | However I still have a problem.
            |
            | I want to make the module available to the
            | caller as if he did an import.
            |
            | For example, if I make the following call
            |
            | some_module.gen erate_module('d ummy')
            |
            | Where some_module is the module that generates
            | modules dinamicaly, and dummy is the name of the
            | new module.
            |
            | I would like to be able to do
            |
            | dummy.something ()
            |
            | after that call.
            |
            | I've discovered that if I do something like this
            |
            | globals()['dummy'] = module_instance _returned_by_ne w.module()
            |
            |
            | It works, but it must be done at the same level I want to
            | call dummy.something () and not from inside some_module. Because
            | if I do it inside the module, globals() will be refering to the
            | module globals and not to parent scope.
            |
            | Basically I would like to import the generated module to the
            | module that is invoking generate_module () like an uplevel in
            | Tcl.
            |
            | Is this possible?

            Sure

            Put this in a file called "dynmods.py " or something:

            from types import ModuleType
            def generate_module (dynmod):

            exec '%(dynmod)s = ModuleType("%(d ynmod)s")' % vars() in globals()
            dynmod = globals()[dynmod]
            exec "def something():\n\ tprint 'hello from', __name__\n" in
            dynmod.__dict__
            return dynmod

            fire up a shell and:
            [color=blue][color=green][color=darkred]
            >>> import dynmods
            >>> dummy = dynmods.generat e_module("dummy ")
            >>> print dummy[/color][/color][/color]
            <module 'dummy' (built-in)>[color=blue][color=green][color=darkred]
            >>> dummy.something ()[/color][/color][/color]
            hello from dummy[color=blue][color=green][color=darkred]
            >>>[/color][/color][/color]

            Is this what you were looking for?

            Regards

            Vincent Wehren


            |
            | Cheers,
            | Paulo Pinto
            |
            | Peter Otten wrote:
            | > Paulo Pinto wrote:
            | >
            | >
            | >>I have a package that generates classes from a
            | >>set of XML files using exec.
            | >>
            | >>So far the classes appear in the global namespace.
            | >>
            | >>Is there any way to also create packages dinamicaly
            | >>and add the classes to those packages?
            | >>
            | >>Thanks in advance,
            | >>Paulo Pinto
            | >
            | >
            | >>>>import types
            | >>>>mymodule = types.ModuleTyp e("mymodule")
            | >>>>exec "def demo():\n\tprin t 'hello from', __name__\n" in
            | >
            | > mymodule.__dict __
            | >
            | >>>>mymodule.de mo()
            | >
            | > hello from mymodule
            | >
            | >
            | > Seems to work. I haven't used it myself, though.
            | >
            | > Peter
            | >
            |


            Comment

            • Naerbnic

              #7
              Re: Build classes/packages dinamicaly

              > I want to make the module available to the[color=blue]
              > caller as if he did an import.
              >
              > For example, if I make the following call
              >
              > some_module.gen erate_module('d ummy')
              >
              > Where some_module is the module that generates
              > modules dinamicaly, and dummy is the name of the
              > new module.
              >
              > I would like to be able to do
              >
              > dummy.something ()
              >
              > after that call.[/color]

              Well, this isn't the perfect solution, but you can create modules in
              the system at runtime like so:

              In your code:[color=blue][color=green][color=darkred]
              >>> mymodule = generate_module () #As above
              >>> import sys
              >>> sys.modules['dummy'] = mymodule[/color][/color][/color]

              Now, the user can just do the following:[color=blue][color=green][color=darkred]
              >>> import dummy
              >>> dummy.something ()[/color][/color][/color]

              It's not _quite_ what you want, since it doesn't automatically include
              it, but it's pretty easy to do. Furthermore, if you standardize the
              name of the module, you can just have the user import that by default,
              and then use whatever dynamic content you've put inside.

              Also, note that mymodule can actually be anything, although you should
              still use a value that responds to __getattr__ (anything else would be
              really confusing, and probably a Bad Thing).

              I hope this helps.

              - Brian Chin

              Comment

              • Paulo Pinto

                #8
                Re: Build classes/packages dinamicaly

                Thanks for the replies.
                I have now a working solution.

                Comment

                Working...