Re: [Zope-dev] How to override __getattr__ and not break acquisition
From: "John Barratt" <[EMAIL PROTECTED]> > Do you mean it only gets [called] when standard (instance & class based) > searching methods fail? Yes. At least, this is what the documentation sais, and it seems to be true as far as I can see. > Object Manager doesn't specifically, but Implicit does, you can see it > if you print out its '__class__.__dict__'. Ah, OK, I never did any really thorough research in that department. I have, in any case, gotten the same results as you, so in that case you probably need to call Implicits.__getattr__ directly. I haven't seen any negative effects of not doing this, though. I'm not well versed enough in how to write python stuff in c, so I don't understand it very well. Just well enough to not be able to find Implicits __getattr__. :-) > Exactly what I need! :-) Thankfully these methods that I need defined > at runtime only come from one other object, so it appears I can override > the __of__ method to work the magic for me in conjunction with > containment acquisition. Yup, much better way. __getattr__ is more for if you have a dictionary which data you want as attributes. ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
> There is no "default" or "normal" __getattr__. __getattr__ is defined only > when you need "abnormal" ways of getting an attribute. Do you mean it only gets defined when standard (instance & class based) searching methods fail? > > If I try a similar thing to this, I always end up getting the 'old' one > > being defined as just the 'raise' statement. > > Thats because ObjectManager doesn't have a __getattr__ . The good > thing with Object Manager doesn't specifically, but Implicit does, you can see it if you print out its '__class__.__dict__'. > this is that you don't have to bother about calling the normal __getattr__. > You only need to implement __getattr__ if you want data that isn't > attributes and has names that are only defined in runtime, to look like they > are attributes. Exactly what I need! :-) Thankfully these methods that I need defined at runtime only come from one other object, so it appears I can override the __of__ method to work the magic for me in conjunction with containment acquisition. Thanks, JB. ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
Casey Duncan wrote: > __getattr__ hooks are evil, only to be used as a last resort. Are you So I've found, >and heard! It didn't stop me from tyring, and I still don't see why they should be >so hard so work with, difficult perhaps, but I wouldn't have though you needed to >pull the seemingly impossible to have them work (with zope at least)! >creating some sort of transparent proxy object? What exactly are you >trying to do? I'm not getting a big picture here. And why do you need See my last post (I posted it before I saw this one sorry), but basically I want a link/reference type functionality that hooks in before containment acquisition, and I think I've worked it out another way to do it as per that post. >to call the inherited __getattr__ from Implicit? Doesn't raising an >AttributeError take care of this? Yes it does, but it wasn't so simple in this case (This is where the 'evil' you mentioned earlier comes in). Part of my problem was the need to call another class method on self which in turn needs to access a method on self that comes from containment acquisition on self, which would call my overridden __getattr__ and have an exception rasied due to not doing containment acquisition. This exeption would then be caught in the code calling the first __getattr__ call, and not the second. Can python not handle exceptions properly with recursive function calls, or was this my bad analysis and/or just being generally confused? > > One other way that may work is to be able to set methods on the object > > as it comes out of the ZODB for use, as I need to be able to get methods > > from other objects in the ZODB, something to explore... Anyone have any > > pointers on this one perhaps? > > Yes, but that would change the attributes and cause the ZODB to save >them on commit (unless you use volatile '_v_' attrs). This might not be >a bad thing. I might be able to use _v_ attrs, otherwise the storing bit would be very bad unless the store method was also overriden and they were deleted on the way out. Thanks, JB. ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
Steve, Thanks for the reply. Steve Alexander wrote: > Sounds like you could use ZPatterns. We already use ZPatterns, but that doesn't seem to fit in at the right layer unfortunately. To further clarify... I am trying to do something similar to what is implemented in Dieter Maurer's 'Reference' product (ie. access another object via a link/reference), and be able to check elswhere for a method/attribute and return it in preference to acquisition (both containment & context based), but not break the acquisition. When I first looked at this product I didn't think it did this quite how I wanted, but I may not have been using it right, as then answer seems to be there, override the __of__ method, and ditch __getattr__! As it stands, I see (think) the standard attribute/method search happens for an Implicit derived class as follows : 1 - Check instance, self.__dict__ 2 - Check class, self.__class__.__dict__ 3 - Check base classes dict, self.__class__.__bases__ __dict__'s etc. 4 - If not found then look for a __getattr__ method and call it. This is implemented in Acquisition.Implicit (c based Extension Class). 5 - Implicit __getattr__ does containment aquisition, __of__. 6 - Implicit __getattr__ does context aquisition, __bobo_traverse__. Overriding __of__ by doing something like : def __of__(self, parent): if not hasattr(parent,'aq_base'): return self ob = self.getTarget() self = Acquisition.ImplicitAcquisitionWrapper(self, ob) self = Acquisition.ImplicitAcquisitionWrapper(self, parent) return self Seems to do the trick as it puts the referenced or linked object in the acquisition chain before the parent. I'm still curious as to know how to get this working with __getattr__ but this other way seems to achieve the same end, and in a similarly elegant fashion. JB. ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
From: "John Barratt" <[EMAIL PROTECTED]> > Basically I want to do something like was demonstrated (using python > 2.1, Zope 2.5.1), but to call the 'default' __getattr__ subsequently so > that I can put in my own handlers, before looking for 'standard' attrs > present on this object through the normal __getattr__ method : There is no "default" or "normal" __getattr__. __getattr__ is defined only when you need "abnormal" ways of getting an attribute. > If I try a similar thing to this, I always end up getting the 'old' one > being defined as just the 'raise' statement. Thats because ObjectManager doesn't have a __getattr__ . The good thing with this is that you don't have to bother about calling the normal __getattr__. You only need to implement __getattr__ if you want data that isn't attributes and has names that are only defined in runtime, to look like they are attributes. Best Regards Lennart Regebro, Torped http://www.easypublisher.com/ ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
On Thu, 17 Oct 2002 19:57:40 +1000 John Barratt <[EMAIL PROTECTED]> wrote: [snip] > > I perhaps should have clarified that I need to be able to specify the > name of the attributes or methods at run time, so ComputedAttribute > unfortunately won't do the trick as you have to define each > attribute/method you require in the class definition. > > ie. I need something like : > def __getattr__(self,attr): >if name in self.methodlist: > >return Implicit.__class__.__getattr__(self,attr) > > where self.methodlist is a list of strings that may change per instance > and/or at runtime, or itself could be calculated at the time of doing > the __getattr__ (eg self.getMethodList()). __getattr__ hooks are evil, only to be used as a last resort. Are you creating some sort of transparent proxy object? What exactly are you trying to do? I'm not getting a big picture here. And why do you need to call the inherited __getattr__ from Implicit? Doesn't raising an AttributeError take care of this? > One other way that may work is to be able to set methods on the object > as it comes out of the ZODB for use, as I need to be able to get methods > from other objects in the ZODB, something to explore... Anyone have any > pointers on this one perhaps? Yes, but that would change the attributes and cause the ZODB to save them on commit (unless you use volatile '_v_' attrs). This might not be a bad thing. -Casey ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
I perhaps should have clarified that I need to be able to specify the name of the attributes or methods at run time, so ComputedAttribute unfortunately won't do the trick as you have to define each attribute/method you require in the class definition. ie. I need something like : def __getattr__(self,attr): if name in self.methodlist: return Implicit.__class__.__getattr__(self,attr) where self.methodlist is a list of strings that may change per instance and/or at runtime, or itself could be calculated at the time of doing the __getattr__ (eg self.getMethodList()). Sounds like you could use ZPatterns. If you do implement your own __getattr__, you might need to check if the object you want to return implements __of__, and return object.__of__(self) (or something like that). -- Steve Alexander ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
Oliver, Thanks for the reply. Oliver Bleutgen wrote: > > def __getattr__(self,attr): > > if name = 'foo': > > return self.foo() > > > > return Implicit.__class__.__getattr__(self,attr) > > If you really want to do just that, take a look at ComputedAttribute, > just in case you don't know. > > foo = ComputedAttribute(_foo) > def _foo(self,..): > > return something I perhaps should have clarified that I need to be able to specify the name of the attributes or methods at run time, so ComputedAttribute unfortunately won't do the trick as you have to define each attribute/method you require in the class definition. ie. I need something like : def __getattr__(self,attr): if name in self.methodlist: return Implicit.__class__.__getattr__(self,attr) where self.methodlist is a list of strings that may change per instance and/or at runtime, or itself could be calculated at the time of doing the __getattr__ (eg self.getMethodList()). One other way that may work is to be able to set methods on the object as it comes out of the ZODB for use, as I need to be able to get methods from other objects in the ZODB, something to explore... Anyone have any pointers on this one perhaps? Thanks, JB. ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
John Barratt wrote: > OK, a bit of python and Zope experimenting and I have got a little > further with this, and my understanding as to when __getattr__ is > actually called! > > This gets closer to working, by calling the __getattr__ from the > Implicit base class, but could be barking up the wrong tree : > > def __getattr__(self,attr): > if name = 'foo': > return self.foo() > > return Implicit.__class__.__getattr__(self,attr) If you really want to do just that, take a look at ComputedAttribute, just in case you don't know. foo = ComputedAttribute(_foo) def _foo(self,..): return something cheers, oliver ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
OK, a bit of python and Zope experimenting and I have got a little further with this, and my understanding as to when __getattr__ is actually called! This gets closer to working, by calling the __getattr__ from the Implicit base class, but could be barking up the wrong tree : def __getattr__(self,attr): if name = 'foo': return self.foo() return Implicit.__class__.__getattr__(self,attr) Except I get a 'TypeError' on the call to the Implicit getattr : "unbound C method must be called with ExtensionClass 1st argument" 'self' inherits from Implicit, so I would have thought this would be OK. Anyone with any thoughts/pointers? TIA, JB. John Barratt wrote: > > Dragging up and old topic here... But I am attempting something similar > here with no success. > > Basically I want to do something like was demonstrated (using python > 2.1, Zope 2.5.1), but to call the 'default' __getattr__ subsequently so > that I can put in my own handlers, before looking for 'standard' attrs > present on this object through the normal __getattr__ method : > > __oldgetattr__ = __getattr__ > def __getattr__(self, name): > if name = 'foo': > return self.foo() > > return self.__oldgetattr__(name) > > However just the assigment of __oldgetattr__ gives an attribute error. > Looking at Andrew Milton's Portable Holes product it seems a similar > attempt to do this is made : > > ... > try: > __oldgetattr__ = ObjectManager.__getattr__ > except: > try: > __oldgetattr__ = ObjectManager.inheritedAttribute('__getattr__') > except: > def __oldgetattr__(self, name): > raise AttributeError, name > ... > > If I try a similar thing to this, I always end up getting the 'old' one > being defined as just the 'raise' statement. All other attempts to > store the 'old' gettattr results in an attribute error. Is this simply > not possible with this version of python and hence the current Zope > release? > > Looks like with 2.2 you can do something like this (taken from Guido's > presentation as OSCON 2001) : > > class C(object): > def __getattr__(self, name): > if name == 'x': return ... > return object.__getattr__(self, name) > > Thanks for any help/pointers! > > JB. > > Casey Duncan wrote: > > > > If your __getattr__ fails to find what it wants, it should raise an > > AttributeError. This will give the ball back to the acquisition > > machinery. > > > > Thusly: > > > > def __getattr__(self, name): > > if name = 'foo': > > return self.foo() > > raise AttributeError, name > > > > hth, > > > > -Casey > > > > On Tue, 2002-06-04 at 22:28, Erik A. Dahl wrote: > > > Ok I need to override __getattr__ in one of my product classes. I'm > > > sure this is killing acquisition but not sure about the persistence > > > stuff (I think this is working). Is there a way to make this work? > > > Here is what I'm doing: > > > > > > def __getattr__(self, name): > > > if name == 'myattr': > > > return self.myattr() > > > > > > > > > I assume that somewhere in the Acquisition code there is a __getattr__ > > > but I can't find it. I tried calling Implicit.__getattr__ but its not > > > there. If some one has an example that would be great. > > > > > > -EAD > > > > > > > > > > > > ___ > > > Zope-Dev maillist - [EMAIL PROTECTED] > > > http://lists.zope.org/mailman/listinfo/zope-dev > > > ** No cross posts or HTML encoding! ** > > > (Related lists - > > > http://lists.zope.org/mailman/listinfo/zope-announce > > > http://lists.zope.org/mailman/listinfo/zope ) > > > > ___ > > Zope-Dev maillist - [EMAIL PROTECTED] > > http://lists.zope.org/mailman/listinfo/zope-dev > > ** No cross posts or HTML encoding! ** > > (Related lists - > > http://lists.zope.org/mailman/listinfo/zope-announce > > http://lists.zope.org/mailman/listinfo/zope ) > > ___ > Zope-Dev maillist - [EMAIL PROTECTED] > http://lists.zope.org/mailman/listinfo/zope-dev > ** No cross posts or HTML encoding! ** > (Related lists - > http://lists.zope.org/mailman/listinfo/zope-announce > http://lists.zope.org/mailman/listinfo/zope ) ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
Dragging up and old topic here... But I am attempting something similar here with no success. Basically I want to do something like was demonstrated (using python 2.1, Zope 2.5.1), but to call the 'default' __getattr__ subsequently so that I can put in my own handlers, before looking for 'standard' attrs present on this object through the normal __getattr__ method : __oldgetattr__ = __getattr__ def __getattr__(self, name): if name = 'foo': return self.foo() return self.__oldgetattr__(name) However just the assigment of __oldgetattr__ gives an attribute error. Looking at Andrew Milton's Portable Holes product it seems a similar attempt to do this is made : ... try: __oldgetattr__ = ObjectManager.__getattr__ except: try: __oldgetattr__ = ObjectManager.inheritedAttribute('__getattr__') except: def __oldgetattr__(self, name): raise AttributeError, name ... If I try a similar thing to this, I always end up getting the 'old' one being defined as just the 'raise' statement. All other attempts to store the 'old' gettattr results in an attribute error. Is this simply not possible with this version of python and hence the current Zope release? Looks like with 2.2 you can do something like this (taken from Guido's presentation as OSCON 2001) : class C(object): def __getattr__(self, name): if name == 'x': return ... return object.__getattr__(self, name) Thanks for any help/pointers! JB. Casey Duncan wrote: > > If your __getattr__ fails to find what it wants, it should raise an > AttributeError. This will give the ball back to the acquisition > machinery. > > Thusly: > > def __getattr__(self, name): > if name = 'foo': > return self.foo() > raise AttributeError, name > > hth, > > -Casey > > On Tue, 2002-06-04 at 22:28, Erik A. Dahl wrote: > > Ok I need to override __getattr__ in one of my product classes. I'm > > sure this is killing acquisition but not sure about the persistence > > stuff (I think this is working). Is there a way to make this work? > > Here is what I'm doing: > > > > def __getattr__(self, name): > > if name == 'myattr': > > return self.myattr() > > > > > > I assume that somewhere in the Acquisition code there is a __getattr__ > > but I can't find it. I tried calling Implicit.__getattr__ but its not > > there. If some one has an example that would be great. > > > > -EAD > > > > > > > > ___ > > Zope-Dev maillist - [EMAIL PROTECTED] > > http://lists.zope.org/mailman/listinfo/zope-dev > > ** No cross posts or HTML encoding! ** > > (Related lists - > > http://lists.zope.org/mailman/listinfo/zope-announce > > http://lists.zope.org/mailman/listinfo/zope ) > > ___ > Zope-Dev maillist - [EMAIL PROTECTED] > http://lists.zope.org/mailman/listinfo/zope-dev > ** No cross posts or HTML encoding! ** > (Related lists - > http://lists.zope.org/mailman/listinfo/zope-announce > http://lists.zope.org/mailman/listinfo/zope ) ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
How about making __setattr__ work ? I keep having Acquisition tell me that it cannot find the Acquisition.Acquired properties. Nic On Wednesday 05 June 2002 09:21 am, Casey Duncan wrote: > If your __getattr__ fails to find what it wants, it should raise an > AttributeError. This will give the ball back to the acquisition > machinery. > > Thusly: > > def __getattr__(self, name): > if name = 'foo': > return self.foo() > raise AttributeError, name > > hth, > > -Casey > > On Tue, 2002-06-04 at 22:28, Erik A. Dahl wrote: > > Ok I need to override __getattr__ in one of my product classes. I'm > > sure this is killing acquisition but not sure about the persistence > > stuff (I think this is working). Is there a way to make this work? > > Here is what I'm doing: > > > > def __getattr__(self, name): > > if name == 'myattr': > > return self.myattr() > > > > > > I assume that somewhere in the Acquisition code there is a __getattr__ > > but I can't find it. I tried calling Implicit.__getattr__ but its not > > there. If some one has an example that would be great. > > > > -EAD > > > ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
If your __getattr__ fails to find what it wants, it should raise an AttributeError. This will give the ball back to the acquisition machinery. Thusly: def __getattr__(self, name): if name = 'foo': return self.foo() raise AttributeError, name hth, -Casey On Tue, 2002-06-04 at 22:28, Erik A. Dahl wrote: > Ok I need to override __getattr__ in one of my product classes. I'm > sure this is killing acquisition but not sure about the persistence > stuff (I think this is working). Is there a way to make this work? > Here is what I'm doing: > > def __getattr__(self, name): > if name == 'myattr': > return self.myattr() > > > I assume that somewhere in the Acquisition code there is a __getattr__ > but I can't find it. I tried calling Implicit.__getattr__ but its not > there. If some one has an example that would be great. > > -EAD > > > > ___ > Zope-Dev maillist - [EMAIL PROTECTED] > http://lists.zope.org/mailman/listinfo/zope-dev > ** No cross posts or HTML encoding! ** > (Related lists - > http://lists.zope.org/mailman/listinfo/zope-announce > http://lists.zope.org/mailman/listinfo/zope ) ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] How to override __getattr__ and not break acquisition
Erik A. Dahl wrote: > Ok I need to override __getattr__ in one of my product classes. I'm > sure this is killing acquisition yes > but not sure about the persistence > stuff (I think this is working). it will still work > Is there a way to make this work? yes > Here is what I'm doing: > > def __getattr__(self, name): >if name == 'myattr': >return self.myattr() if your return value knows about acquisition, you need to it by calling __of__: def __getattr__(self, name): if name == 'myattr': return self.myattr().__of__(self) > I assume that somewhere in the Acquisition code there is a __getattr__ > but I can't find it. it is implemented in C. -- Steve Alexander ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )