473,421 Members | 1,631 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,421 software developers and data experts.

How to load new class definitions at runtime?

I'm looking for ways to load new class definitions at runtime (I'm not
talking about object instances here, so a persistent object database
isn't what I am looking for [1]). I'm aware of a few options, but I
would like to discuss the possible side effects for a potentially big,
long running application server.

I am developing a business application based on workflow concepts. The
model is quite simple: a business process is modelled as a sequence of
tasks connected by actions. Actions can be re-used in different
contexts. The result is a very complex graph. Processes, tasks and
actions are implemented as classes. I opted to declare each action as
a different class, because each action has different Python code
attached to it. So simple object instances would not cut it. To allow
the system to be customized without taking the application server
offline, there must be a solution for these new class definitions to
be loaded at runtime.

My current solution is simple. Class definitions have to be executed,
and for it to work, the class name and the source code (or the
compiled bytecode) is stored in a database. A class factory function
retrieves the correct class definition (based on the name), and simply
executes the code.

Now, talking about executing arbitrary code retrieved from a database
isn't exactly a safe proposition. But I can't see any other way to
make it work. I'm now looking for more ideas on how do other people
solved the same problem in other projects. Pointers are welcome.
Thanks in advance,

---
[1] ... or at least I assume so.
--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #1
7 1698
Carlos Ribeiro <ca********@gmail.com> wrote:
...
attached to it. So simple object instances would not cut it. To allow
the system to be customized without taking the application server
offline, there must be a solution for these new class definitions to
be loaded at runtime.
If you need them to be _updatable_ at runtime, look at a recipe by
Michael Hudson in the cookbook -- I've updated it for the printed
version 2nd ed (since we do have __subclasses__ now, yay!) but that's
not done yet. My vote for most useful custom metaclasses ever...
My current solution is simple. Class definitions have to be executed,
and for it to work, the class name and the source code (or the
compiled bytecode) is stored in a database. A class factory function
retrieves the correct class definition (based on the name), and simply
executes the code.
You can pickle the bytecode etc (again, cookbook recipes show how) but
that has no real advantage wrt storing the source or bytecode. Just
make sure, for performance, that if you store the source the bytecode
also gets stashed away when first made. Unless for some weird reason
you need your code repository to support multiple releases of Python at
the same time (eek), you might as well store the bytecode at the time
the source is stored -- upgrading release of Python in the future _will_
require a DB conversion and some downtime for the switch.
Now, talking about executing arbitrary code retrieved from a database
isn't exactly a safe proposition. But I can't see any other way to
make it work. I'm now looking for more ideas on how do other people
solved the same problem in other projects. Pointers are welcome.


If you want to allow arbitrary class definitions to happen at runtime,
"a safe proposition" is an oxymoron -- obviously you have to trust
*entirely* the repository of the code (and pickles would be just about
the same thing). Digital signatures to ensure the repository has not
been tampered with would also need to be stored somewhere entirely
trustable, so you might as well declare that the trust must be towards
the repository, in all practical cases I can think of.
From past experience with this sort of thing, my practical suggestion
is: make sure you have a development/debug mode in which the classes are
first looked for on ordinary modules in the filesystem, then gotten from
the DB only if the ordinary modules don't have them. When you're
developing and debugging, you'll heavily use this feature, believe me,
and also Michael Hudson's recipe above-mentioned, since tweaks and mods
to the classes will come at a hefty pace.

It's a harder deployment decision whether the normal system operation
should also support the filesystem, or just the database. The latter
makes development less convenient, but distributed processing much
easiery to manage, updates are transactional and atomic, etc. It
depends on how much customization-during-operation you'll need, vs the
other deployment issues.
Alex
Jul 18 '05 #2
On Sun, 14 Nov 2004 10:07:01 +0100, Alex Martelli <al*****@yahoo.com> wrote:
Carlos Ribeiro <ca********@gmail.com> wrote:
...
attached to it. So simple object instances would not cut it. To allow
the system to be customized without taking the application server
offline, there must be a solution for these new class definitions to
be loaded at runtime.
If you need them to be _updatable_ at runtime, look at a recipe by
Michael Hudson in the cookbook -- I've updated it for the printed
version 2nd ed (since we do have __subclasses__ now, yay!) but that's
not done yet. My vote for most useful custom metaclasses ever...


Thanks for the pointer. Michael Hudson's recipe solves one huge part
of the problem; I was not even trying to solve it yet, but it helps a
lot :-)

[snip] It's a harder deployment decision whether the normal system operation
should also support the filesystem, or just the database.


I'm thinking about two alternatives right now, not mutually exclusive.

1) I'm trying to understand how do packages work, and what hooks are
available. I guess I could make it work using packages to re-read the
source code whenever a "from <package> import <module>" statement is
executed; Michael Hudson's recipe could also be automatically invoked
for the redefined classes.

2) Another suggestion is to use a source-code control system as the
code repository. For example: using the Python Subversion interface, I
could checkout the code for the class. It's safer, in a sense, than
database access, because of the way it tracks changes and logs
accesses. But it's also more complex, and possibly slower, than a file
read, or even a database read (depending on the db engine, of course).

My choice now is a simple-minded 'always re-read the source code'
approach, just to make it work and test some concepts. But the problem
seems interesting enough to deserve further investigation. I'm sure a
"dynamic package" version, with automatic redefinition using the
Michaels Hudson's recipe, would make for a good recipe itself.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: ca********@gmail.com
mail: ca********@yahoo.com
Jul 18 '05 #3
SM
al*****@yahoo.com (Alex Martelli) wrote in message news:<1gn8ja3.7d3sbhuk94khN%al*****@yahoo.com>...
If you need [classes] to be _updatable_ at runtime, look at a recipe by
Michael Hudson in the cookbook -- I've updated it for the printed
version 2nd ed (since we do have __subclasses__ now, yay!) but that's
not done yet. My vote for most useful custom metaclasses ever...


That recipe is here:
http://aspn.activestate.com/ASPN/Coo.../Recipe/160164

Is it correct that this metaclass solution does not handle changes to
__init__, including new attributes that are bound there? I.e., it
basically only deals with modification or addition or deletion of
methods; if you need to add new attributes or have any other new code
in __init__, you'll have to make new instances for all the old
instances, or deal with it some other way. In which case would you be
better off just using that other way from the start?
Jul 18 '05 #4
Hi,
I am a newbie here. I want to know how to redirect os.system("ls -af")
to a string variable without it barfing the answer of ls -af on the
screen.

Thanks in advance,
Madhusudhanan.C
Jul 18 '05 #5
SM <sj******@gmail.com> wrote:
al*****@yahoo.com (Alex Martelli) wrote in message news:<1gn8ja3.7d3sbhuk94khN%al*****@yahoo.com>...
If you need [classes] to be _updatable_ at runtime, look at a recipe by
Michael Hudson in the cookbook -- I've updated it for the printed
version 2nd ed (since we do have __subclasses__ now, yay!) but that's
not done yet. My vote for most useful custom metaclasses ever...


That recipe is here:
http://aspn.activestate.com/ASPN/Coo.../Recipe/160164

Is it correct that this metaclass solution does not handle changes to
__init__, including new attributes that are bound there? I.e., it


It doesn't rerun __init__ nor any other method on existing instances.
basically only deals with modification or addition or deletion of
methods; if you need to add new attributes or have any other new code
in __init__, you'll have to make new instances for all the old
instances, or deal with it some other way. In which case would you be
better off just using that other way from the start?


It's pretty trivial to enhance the recipe to run a per-instance or
per-subclass __make_old_into_new__ method, if that method exists, on all
existing old instances -- if you need to adjust the old instances'
states (==attributes), that strikes me as the best architecture.
Alex
Jul 18 '05 #6
Madhusudhanan Chandrasekaran <mc**@cse.buffalo.edu> writes:
Hi,
I am a newbie here. I want to know how to redirect os.system("ls -af")
to a string variable without it barfing the answer of ls -af on the
screen.

Thanks in advance,
Madhusudhanan.C


1. If all you want is the list of files:
myfiles=os.listdir('.')

2. If you want exactly the ls commands output, simplest is:
import commands
result=commands.getoutput("ls -af")

3. If you want more control, you may need forking and piping.
Let me know if you need examples.

--
ha************@boeing.com
6-6M21 BCA CompArch Design Engineering
Phone: (425) 294-4718
Jul 18 '05 #7
al*****@yahoo.com (Alex Martelli) writes:
SM <sj******@gmail.com> wrote:
al*****@yahoo.com (Alex Martelli) wrote in message

news:<1gn8ja3.7d3sbhuk94khN%al*****@yahoo.com>...
If you need [classes] to be _updatable_ at runtime, look at a recipe by
Michael Hudson in the cookbook -- I've updated it for the printed
version 2nd ed (since we do have __subclasses__ now, yay!) but that's
not done yet. My vote for most useful custom metaclasses ever...

Wow, thanks :)
That recipe is here:
http://aspn.activestate.com/ASPN/Coo.../Recipe/160164

Is it correct that this metaclass solution does not handle changes to
__init__, including new attributes that are bound there? I.e., it


It doesn't rerun __init__ nor any other method on existing instances.


Well... it runs change_class on existing instances, but see below...
basically only deals with modification or addition or deletion of
methods; if you need to add new attributes or have any other new code
in __init__, you'll have to make new instances for all the old
instances, or deal with it some other way. In which case would you be
better off just using that other way from the start?


It's pretty trivial to enhance the recipe to run a per-instance or
per-subclass __make_old_into_new__ method, if that method exists, on all
existing old instances -- if you need to adjust the old instances'
states (==attributes), that strikes me as the best architecture.


I'd sort of thought about this when I wrote the recipe initially --
it's why there is a change_class method -- but now realize that it
doesn't really work, because when you reload the module, it runs the
*old* change_class when it would (obviously) be much more useful to
somehow run a new method.

How about this diff (from what's on the recipe page now):

*** autoreloader.py~ 2004-10-27 17:50:03.000000000 +0100
--- autoreloader.py 2004-11-26 11:36:45.000000000 +0000
***************
*** 27,33 ****
if d.has_key(name):
old_class = d[name]
for instance in old_class.__instances__():
! instance.change_class(new_class)
new_class.__instance_refs__.append(
weakref.ref(instance))
# this section only works in 2.3
--- 27,34 ----
if d.has_key(name):
old_class = d[name]
for instance in old_class.__instances__():
! instance.__class__ = new_class
! instance.update_self()
new_class.__instance_refs__.append(
weakref.ref(instance))
# this section only works in 2.3
***************
*** 44,51 ****

class AutoReloader:
__metaclass__ = MetaAutoReloader
! def change_class(self, new_class):
! self.__class__ = new_class

class Bar(AutoReloader):
pass
--- 45,52 ----

class AutoReloader:
__metaclass__ = MetaAutoReloader
! def update_self(self):
! pass

class Bar(AutoReloader):
pass
***************
*** 67,69 ****
--- 68,94 ----
b2.meth(2)
# new Baz() instances now play too:
Baz().meth(3)
+
+ class C(AutoReloader):
+ def __init__(self, a):
+ self.a = 1
+ def get_attribute(self):
+ return self.a
+
+ c = C(1)
+
+ print c.get_attribute()
+
+ class C(AutoReloader):
+ def __init__(self, b):
+ self.b = b
+ def get_attribute(self):
+ return self.b
+
+ def update_self(self):
+ self.b = self.a
+ del self.a
+
+ print c.get_attribute()
+
+

Probably a bit more useful, though it has the disadvantage that it
will crash and burn if you forget to remove the update_self() method
before reloading again (that's probably inevitable, though). Maybe
you could introduce revision numbers on the instances and the classes
or something, though this might be getting a little complex.

Cheers,
mwh

--
Important data should not be entrusted to Pinstripe, as it may
eat it and make loud belching noises.
-- from the announcement of the beta of "Pinstripe" aka. Redhat 7.0
Jul 18 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: angel | last post by:
A java runtime environment includes jvm and java class (for example classes.zip in sun jre). Of course jython need jvm,but does it need java class. Thanx
8
by: Martin Magnusson | last post by:
I want to create a few objects which all share a lot of common features, so they should all derive from the same base class. However, each of them needs individual definitions of two functions. So...
9
by: John Kirksey | last post by:
I have a page that uses an in-place editable DataGrid that supports sorting and paging. EnableViewState is turned ON. At the top of the page are several search fields that allow the user to filter...
1
by: Reza Nabi | last post by:
Bakground: I have a webform (LoadCtl.aspx) which loads the user control to a placeholder dynamically based on the ctlName querystring passed in the URL. Webform (LoadCtl.aspx) also passes a...
6
by: Steve | last post by:
I'm playing with late binding and trying a very simple test to load an assembly In my "Host" application I have this code: <code> string modulePath =...
9
by: S Wheeler | last post by:
Hi all - I am trying to create an instance of a vb .net class containing a form from unmanaged vc++. The vb.net is a dll. How to do this ? I am trying #import by can't seem to get it quite...
10
by: Ognen Duzlevski | last post by:
Hi, I have a "language definition" file, something along the lines of: page :: name : simple caption : simple function : complex function :: name : simple code : simple
0
Ensonix
by: Ensonix | last post by:
I found a post about this, and it had some C# code that wouldn't convert, and when I finally got it converted it didn't work in .NET 1.1. So I made a few changes to the converted VB version and now...
4
hemantbasva
by: hemantbasva | last post by:
We have designed an aspx page having five ajax tab in it. the data of first four are designed on page whereas for the fifth tab it renders a user control named MYDOMAIN. in the tab container's even...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.