[Tutor] checking for class version info.

Bob Gailer bgailer@alum.rpi.edu
Thu Jul 3 22:04:01 2003


--=======4B2D47A0=======
Content-Type: multipart/alternative; x-avg-checked=avg-ok-7B3454B; boundary="=====================_44158977==.ALT"


--=====================_44158977==.ALT
Content-Type: text/plain; x-avg-checked=avg-ok-7B3454B; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 8bit

At 11:23 AM 7/4/2003 +1200, you wrote:

>i guess that from the HUGE non-reply this thread has gotten that it's
>not possible, correct?

OK, I'll take a shot at it.

At 11:39 PM 7/2/2003 +1200, Thomas CLive Richards wrote:
>I have developed a small program which saves (using the pickle module)
>some classes, and loads them at a later date. The trouble is, the
>program is under active development, and the contents of the classes are
>changing constantly. What i would like to do, is invent some way so that
>as the classes are loaded, they automatically detect if they are the
>save "version" as the current class in the program source file. If they
>are not, they somehow "re-initialise" themselves in the new class. does
>that make sense?

It does, but you may be confusing classes and instances. The instances are 
what you'd need to re-initialise, no?

>the first way i thought i would do it is generate some sort of unique
>identifier for the source code file each class is in (the code is such
>that every class is in a separate file - this cannot be changed); the
>size of the file in bytes would probably be enough for this (or perhaps
>the last modification time?). However, that would mean that simple
>adding a comment to the class would cause the class to reload, and that
>wouldn't be too good.
>
>then i thought about having a variable in each class called "version",
>or something similar, so that when a developer updates a class
>significantly, he can change the version number, and the classes would
>reload themselves, if their version number didn't match that in the
>class source code file. The trouble with that is that developers are
>lazy, and would probably forget.
>
>Also, i have no idea how to go about doing this "reloading". It may be
>that the objects will have to be re-created every time the class
>changes, or that I'll have to make a conversion script, but there you go

Here is how pickle handles re-initialising. From the pickle docs:

"When a pickled class instance is unpickled, its __init__() method is 
normally not invoked. If it is desirable that the __init__() method be 
called on unpickling, a class can define a method __getinitargs__(), which 
should return a tuple containing the arguments to be passed to the class 
constructor (i.e. __init__()). The __getinitargs__() method is called at 
pickle time; the tuple it returns is incorporated in the pickle for the 
instance.

Classes can further influence how their instances are pickled; if the class 
defines the method __getstate__(), it is called and the return state is 
pickled as the contents for the instance, instead of the contents of the 
instance's dictionary. If there is no __getstate__() method, the instance's 
__dict__ is pickled.
Upon unpickling, if the class also defines the method __setstate__(), it is 
called with the unpickled state. If there is no __setstate__() method, the 
pickled object must be a dictionary and its items are assigned to the new 
instance's dictionary. If a class defines both __getstate__() and 
__setstate__(), the state object needn't be a dictionary and these methods 
can do what they want."

Based on this you could accomplish the mechanics by using __getinitargs__ 
or __setstate__. Here's how __getinitargs__ could work:

design __init__ to take a version # as an argument. Save the old version 
number (class property) using __getinitargs__ and have  __init__ compare 
that to the current version number to decide if things needed to be 
re-initialised.

class Foo:

   def __init__(self, version):
     if version != self.version:
       reinitialise code goes here
       self.version = '0.9.1'

   def __getinitargs__():
       return (self.version, )

The issue of HOW to recognize changes or enforce developers to maintain 
version #s is of course a different topic.

Bob Gailer
bgailer@alum.rpi.edu
303 442 2625


--=====================_44158977==.ALT
Content-Type: text/html; x-avg-checked=avg-ok-7B3454B; charset=us-ascii
Content-Transfer-Encoding: 8bit

<html>
<body>
At 11:23 AM 7/4/2003 +1200, you wrote:<br><br>
<blockquote type=cite class=cite cite>i guess that from the HUGE
non-reply this thread has gotten that it's<br>
not possible, correct?</blockquote><br>
OK, I'll take a shot at it.<br><br>
At 11:39 PM 7/2/2003 +1200, Thomas CLive Richards wrote:<br>
<blockquote type=cite class=cite cite>I have developed a small program
which saves (using the pickle module)<br>
some classes, and loads them at a later date. The trouble is, the<br>
program is under active development, and the contents of the classes
are<br>
changing constantly. What i would like to do, is invent some way so
that<br>
as the classes are loaded, they automatically detect if they are 
the<br>
save &quot;version&quot; as the current class in the program source file.
If they<br>
are not, they somehow &quot;re-initialise&quot; themselves in the new
class. does<br>
that make sense?</blockquote><br>
It does, but you may be confusing classes and instances. The instances
are what you'd need to re-initialise, no?<br><br>
<blockquote type=cite class=cite cite>the first way i thought i would do
it is generate some sort of unique<br>
identifier for the source code file each class is in (the code is
such<br>
that every class is in a separate file - this cannot be changed);
the<br>
size of the file in bytes would probably be enough for this (or
perhaps<br>
the last modification time?). However, that would mean that simple<br>
adding a comment to the class would cause the class to reload, and
that<br>
wouldn't be too good. <br><br>
then i thought about having a variable in each class called
&quot;version&quot;,<br>
or something similar, so that when a developer updates a class<br>
significantly, he can change the version number, and the classes
would<br>
reload themselves, if their version number didn't match that in the<br>
class source code file. The trouble with that is that developers 
are<br>
lazy, and would probably forget.<br><br>
Also, i have no idea how to go about doing this &quot;reloading&quot;. It
may be<br>
that the objects will have to be re-created every time the class<br>
changes, or that I'll have to make a conversion script, but there you
go</blockquote><br>
Here is how pickle handles re-initialising. From the pickle docs:
<br><br>
&quot;When a pickled class instance is unpickled, its <tt>__init__()</tt>
method is normally <i>not</i> invoked. If it is desirable that the
<tt>__init__()</tt> method be called on unpickling, a class can define a
method <tt>__getinitargs__()</tt>, which should return a <i>tuple</i>
containing the arguments to be passed to the class constructor (i.e.
<tt>__init__()</tt>). The <tt>__getinitargs__()</tt> method is called at
pickle time; the tuple it returns is incorporated in the pickle for the
instance.<br><br>
Classes can further influence how their instances are pickled; if the
class defines the method <tt>__getstate__()</tt>, it is called and the
return state is pickled as the contents for the instance, instead of the
contents of the instance's dictionary. If there is no
<tt>__getstate__()</tt> method, the instance's <tt>__dict__</tt> is
pickled. <br>
Upon unpickling, if the class also defines the method
<tt>__setstate__()</tt>, it is called with the unpickled state. If there
is no <tt>__setstate__()</tt> method, the pickled object must be a
dictionary and its items are assigned to the new instance's dictionary.
If a class defines both <tt>__getstate__()</tt> and
<tt>__setstate__()</tt>, the state object needn't be a dictionary and
these methods can do what they want.&quot;<br><br>
Based on this you could accomplish the mechanics by using
<tt>__getinitargs__</tt> or <tt>__setstate__.</tt> Here's how
<tt>__getinitargs__ could work:<br><br>
</tt>design <tt>__init__</tt> to take a version # as an argument. Save
the old version number (class property) using <tt>__getinitargs__</tt>
and have&nbsp; <tt>__init__</tt> compare that to the current version
number to decide if things needed to be re-initialised.<br><br>
<tt>class Foo:<br><br>
&nbsp; def __init__(self, version):<br>
&nbsp;&nbsp;&nbsp; if version != self.version:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reinitialise code goes here<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.version = '0.9.1'<br><br>
&nbsp; def __getinitargs__():<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (self.version, )<br><br>
</tt>The issue of HOW to recognize changes or enforce developers to
maintain version #s is of course a different topic.<br>
<x-sigsep><p></x-sigsep>
Bob Gailer<br>
bgailer@alum.rpi.edu<br>
303 442 2625<br>
</body>
</html>


--=====================_44158977==.ALT--

--=======4B2D47A0=======
Content-Type: text/plain; charset=us-ascii; x-avg=cert; x-avg-checked=avg-ok-7B3454B
Content-Disposition: inline


---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.492 / Virus Database: 291 - Release Date: 6/24/2003

--=======4B2D47A0=======--