Hello everyone, I just updated the Zope 3 FAQ at: http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/FAQ While we have already many great questions (and hopefully good answers), I would like to receive some more. I will make a serious effort in the next week on answering all the questions that have been submitted either to me or as comments on the Wiki. Regards, Stephan -- Stephan Richter CBU Physics & Chemistry (B.S.) / Tufts Physics (Ph.D. student) Web2k - Web Software Design, Development and Training
On Fri, Apr 04, 2003 at 07:35:19PM -0500, Stephan Richter wrote:
Hello everyone,
I just updated the Zope 3 FAQ at: http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/FAQ
While we have already many great questions (and hopefully good answers), I would like to receive some more. I will make a serious effort in the next week on answering all the questions that have been submitted either to me or as comments on the Wiki.
Hi Stephan, I attached a new question: Will the request and the response be written in capital letters? I prefere them to be written like normal variables. Questions which are longer than one line are not bold. I tried to change this, but my browser wraps the lines automaticaly. thomas -- Thomas Guettler <guettli@thomas-guettler.de> http://www.thomas-guettler.de
On Saturday 05 April 2003 06:53, Thomas Guettler wrote:
Questions which are longer than one line are not bold. I tried to change this, but my browser wraps the lines automaticaly.
I fixed that now. Regards, Stephan -- Stephan Richter CBU Physics & Chemistry (B.S.) / Tufts Physics (Ph.D. student) Web2k - Web Software Design, Development and Training
On Fri, Apr 04, 2003 at 07:35:19PM -0500, Stephan Richter wrote:
Hello everyone,
I just updated the Zope 3 FAQ at: http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/FAQ
New question: Will there be a "standard" way of updating existing instances to changes in the python source? Upto now I my python classes have a refresh() method wich updates instances which are already in ZODB. I prefere this explizit method to the implicit update when the object gets unpickled. I think we just need to agree on the name of this method. thomas -- Thomas Guettler <guettli@thomas-guettler.de> http://www.thomas-guettler.de
On Saturday 05 April 2003 07:37, Thomas Guettler wrote:
On Fri, Apr 04, 2003 at 07:35:19PM -0500, Stephan Richter wrote:
Hello everyone,
I just updated the Zope 3 FAQ at: http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/FAQ
New question:
Will there be a "standard" way of updating existing instances to changes in the python source?
Upto now I my python classes have a refresh() method wich updates instances which are already in ZODB. I prefere this explizit method to the implicit update when the object gets unpickled.
I think you are using Zope wrong. You do not need such a methid, the Transaction machinery does it for you. If you have a dictionary, you should use persistent dictionary, so it will be updated. I am positive that there will be never something like a refresh() method in Zope, either Zope 2 or 3. Regards, Stephan -- Stephan Richter CBU Physics & Chemistry (B.S.) / Tufts Physics (Ph.D. student) Web2k - Web Software Design, Development and Training
On Sat, Apr 05, 2003 at 08:06:40AM -0500, Stephan Richter wrote:
On Saturday 05 April 2003 07:37, Thomas Guettler wrote:
On Fri, Apr 04, 2003 at 07:35:19PM -0500, Stephan Richter wrote:
Hello everyone,
I just updated the Zope 3 FAQ at: http://dev.zope.org/Wikis/DevSite/Projects/ComponentArchitecture/FAQ
New question:
Will there be a "standard" way of updating existing instances to changes in the python source?
Upto now I my python classes have a refresh() method wich updates instances which are already in ZODB. I prefere this explizit method to the implicit update when the object gets unpickled.
I think you are using Zope wrong. You do not need such a methid, the Transaction machinery does it for you. If you have a dictionary, you should use persistent dictionary, so it will be updated.
No, you missunderstood me. Example: You created instances of you class Foo. You have about 1000 instances of this in the ZODB. Now you change the source of your python code, that all *new* objects get a birthday: new code: class Foo: def __init__(self): self.birthday=time.time() If your application is already used by some people, you can't delete the 1000 existing objects which don't have a birthday. You need a way to update them. In this example you need to set the birthday for the old objects. You could set the birthday in __setstate__(). This is called when the objects gets unpickled. But I had problems with it. I think it is because the objects in memory are already unpickled, thus they don't get updated. The solution is quite easy: All objects have a refreshAllObjects() method, which gets called from me if you do relevant changes. OK, this does not scale since all objects are touched, but it works for my use-case. I hope you understood what I mean. If not, please ask! thomas -- Thomas Guettler <guettli@thomas-guettler.de> http://www.thomas-guettler.de
On Sat, 2003-04-05 at 08:23, Thomas Guettler wrote:
Example: You created instances of you class Foo. You have about 1000 instances of this in the ZODB. Now you change the source of your python code, that all *new* objects get a birthday:
new code:
class Foo: def __init__(self): self.birthday=time.time()
Right... all *new* objects get a birthday. Since that's how you've described (and coded) the change, existing objects won't have a birthday attribute until you give them one. If that's not what you want, then don't do it that way.
If your application is already used by some people, you can't delete the 1000 existing objects which don't have a birthday. You need a way to update them. In this example you need to set the birthday for the old objects.
If you want existing objects to have immediate use of new attributes, you need only code it that way. There is no need to devise a workaround for having mis-defined the requirement. ----- class Foo(base_classes): def __init__(self): # avoid doing stuff here pass # add the following to a class with existing instances birthday = 0 def set_birthday(self): self.birthday = time.time() def show_birthday(self): return self.birthday ----- Now all existing instances will *immediately* have access to a birthday attribute, since it is a class variable. The moment you assign to self.birthday, a new variable is created that is local to that instance. Note, in particular, that it doesn't matter whether set_birthday() is called before show_birthday(). The fact that there is a class variable called birthday is sufficient to resolve the name. You can think of the class variable as a default or fall-through value. If that default is changed, the changes will be immediately reflected in all instances that *haven't* assigned a specific, overriding value. Taking this a step further, it's probably a better idea to use class variables to initialize attributes rather that putting them in __init__() unless your *explicit intent* is to have different instances preserving the assumptions they were created with. Coding this way also makes the current state of your objects more obvious from the code and makes subclassing more transparent. Class variables are particularly well-used when your instances are storing some bit of information that's the same value among all (or most) instances. Note, for example, that this is how common attributes such as meta_type and interfaces are implemented. You *could* have different instances determine (and remember) their own meta_type or unique interface when they are initialized, but for the most part, that's not what you want.
The solution is quite easy: All objects have a refreshAllObjects() method, which gets called from me if you do relevant changes. OK, this does not scale since all objects are touched, but it works for my use-case.
You can do this (and I have). But it seems far easier to implement the behavior you want than to create a kludge layer. Dylan
On Sat, Apr 05, 2003 at 11:32:08AM -0800, Dylan Reinhardt wrote:
class Foo(base_classes): def __init__(self): # avoid doing stuff here pass
# add the following to a class with existing instances birthday = 0
def set_birthday(self): self.birthday = time.time()
def show_birthday(self): return self.birthday
-----
Now all existing instances will *immediately* have access to a birthday attribute, since it is a class variable. The moment you assign to self.birthday, a new variable is created that is local to that instance.
True, and I've used this idiom quite a bit... BUT I must warn any python newbies following this discussion that you can't use the same trick when modifying mutable attributes. You need to be sure to reassign the attribute, not just modify it in place. If you do the latter you'll just modify the class attribute and all instances will see the modification. Example:
class Foo: ... immutable = 0 ... mutable = [0, 1, 2] ... x = Foo() y = Foo() # now let's change y ... y.immutable = "not the original" # now let's examine them ... x.immutable 0 y.immutable 'not the original' # so far so good. what about the list? ... y.mutable[0] = "also not the original" x.mutable ['also not the original', 1, 2] # oops! we've changed mutable[0] for ALL instances.
-- Paul Winkler http://www.slinkp.com Look! Up in the sky! It's THE PAINTED FANG! (random hero from isometric.spaceninja.com)
participants (4)
-
Dylan Reinhardt -
Paul Winkler -
Stephan Richter -
Thomas Guettler