[Zope] Subclassing from Custom Python Classes

Pete Kazmier pete@kazmier.com
Wed, 24 May 2000 20:31:48 -0400


Thank you for the useful information!!

I do have one more question regarding your persistence comments.  How
does using a temporary name notify the Zope persistence machinery that
self.map has changed?  Doesn't 'self.map=m' do nothing in Python if
one already did a 'm=self.map'?  In the end, aren't they referencing
the exact same object?  Hows does Zope know its different?

Thanks again,
Pete

On Wed, May 24, 2000 at 12:38:03AM -0400, Chris McDonough wrote:
> > >> You should also note that your subclass must obey the ZODB
> > >> persistence rules, which basically state that mutable sub-objects
> > >> should be treated immutably. For example,
> > >>
> > >> self.bird='parrot' # OK
> > >> self.map['bird']='parrot' # NOT OK, will not trigger persistence
> > >>                             machinery
> > >> m=self.map
> > >> m['bird']='parrot'
> > >> self.map=m # OK, treats a mutable object immutably
> > 
> > What are these "persistence rules" and how come the second example is
> > ok?  I thought in Python, when you assign "m = self.map" that m is
> > simply pointing to the same object as self.map and that any changes to
> > m affect self.map too?  Does the "self.map = m" have any effect?
> > Don't they point to the same object?
> 
> It's a long story.  :-)  Attributes of Zope objects need to play by some
> ground rules to be persistent.  The description in the docs is sort of a
> half truth.  It works as described, but you can also do something like:
> 
> self.map['bird'] = 'parrot'
> self._p_changed = 1
> 
> to trigger the persistence machinery.  The "m=self.map..." stuff in the
> example does the same thing.  In either case you're bringing it to
> Zope's attention that it needs to at some point re-write the object
> referred to by "self" out to the ZODB.  By doing the jiggery up there
> where you use "m" as a temp object, operate on it, and then reassign
> "self.map" to "m" in order to let Zope know you've really changed the
> object and that you really want to write a new copy of it out to the
> ZODB when it's convenient for it to do so.  the _p_changed flag applies
> to any Zope object, and just needs to be set true at some point during
> the method to let the persistence machinery know that the object has
> changed state.
> 
> In english the phrase "mutable sub-objects should be treated immutably"
> means that attributes of the Zope object you're mucking with that can be
> reassigned "in-place" (things you can append to like a list, or add
> items to like a dictionary) should be treated as though they can't be.
> So when saying (where 'self' is a Zope object):
> 
> self.mylist.append("foo")
> 
> This should be given special treatment, either by saying:
> 
> self.mylist.append("foo")
> self._p_changed = 1
>  
> or
> 
> mytmp = self.mylist
> mytmp.append("foo")
> self.mylist = mytmp
> 
> > 
> > I ask because I've already built my first product based on a custom
> > python class I wrote (its a router object that has methods to query
> > various snmp oids) based on a ZClass and I want to make sure that I am
> > not doing anything wrong.
> > In addition to the methods that query the oids, I store the results in
> > an instance variable of my Python class so I can cache the information
> > for a specified amount of time.  Is this safe to do?  Can I store
> > these values in my Python instance (self.xxxx), not a ZClass property?
> 
> Sure, just make sure you abide by the stuff above.
> 
> > Also, What happens if multiple people activate my query method, do I
> > need to worry about them stomping over each other as the method writes
> > the results to the instance variables?  Is there any record locking of
> > objects?
> 
> The ZODB will flag a ConflictError and will cause the second attempter
> to retry.  This is pretty normal, and your data won't get munged.  Look
> out, however, if you're really concerned, about "hot spots" that can
> effect performance.
>  
> > Lastly, since I couldn't really find any pointers regarding a builtin
> > Zope scheduler that is bug free, I need to write a small python script
> > that I can place in a cron job to run every ten minutes to call the
> > query methods of these objects so they update their cache instances.
> > Is there a link on how to get a regular Python script access to the
> > ZODB?
> 
> Yes... sort of.  Try looking for a HowTo named "The Debugger is Your
> Friend" by Michel Pelletier.  That shows you how to use the Zope module
> from inside python.  It's simpler than you might expect.  Here's an
> example (make sure you shut down your Zope before you try this or it
> won't work):
> 
> [chrism@opar chrism]$ cd Zope2.1.6/lib/python
> [chrism@opar chrism]$ python
> >>> import Zope
> >>> app = Zope.app()
> >>> app
> <Application instance at 8455220>
> >>> dir(app)
> ['Control_Panel', '__allow_groups__'........]
> 
> Play around inside Python, call methods on things, etc.  This is a great
> way to learn more about Zope.
>  
> 
> _______________________________________________
> Zope maillist  -  Zope@zope.org
> http://lists.zope.org/mailman/listinfo/zope
> **   No cross posts or HTML encoding!  **
> (Related lists - 
>  http://lists.zope.org/mailman/listinfo/zope-announce
>  http://lists.zope.org/mailman/listinfo/zope-dev )
> 

-- 
Peter Kazmier                                 http://www.kazmier.com
PGP Fingerprint   4FE7 8DA3 D0B5 9CAA 69DC  7243 1855 BC2E 4B43 5654