RE: [Zope] Re: Problem with hasattr() and Zope 2.8.1
Your example shows my problem, or what I see as a problem anyways: def __init__(self): self.__blech = 1 def do(self): print hasattr(self, "__blech") >>> x = Foo() >>> x.do() False False? Really? hasattr() is used within the context of the class itself, so the fact it's "private" shouldn't be a problem, should it? If I was using hasattr() outside the scope/context of the class/instance, then ok ... But within it? I'm not breaking any "privacy" rules by doing this ... I'd expect the (un)mangling to be applied here. Of course, hasattr() is a standalone function ... So maybe that's a factor. Unintuitive behavior, I say ... Maybe I'll take this to c.l.p :) So how does an instance test whether it has a private attribute set? Is it really proper for to unmangle "manually"? (This would strike me as bad form when already working within the class/instance) So then that leaves me wondering why my other pieces of code DON'T do this, and work the way I initially expect ... No, my "lang" never ends in an "_" ... It's always __attname_en for example, or __attname_fr ... Etc ... These are internal attributes wrapped by properties, though there is some metaclass trickery going on here as well ... Might be a factor? The fact some of the related logic (too long to show here, unless you're really interested) is dynamically bound through metaclasses maybe changes the scope of the attribute, and hence its mangling behavior? Basically I use something like the "autoprop" examples from the Python docs to do multilingual objects, where the language differences are handled at the property level (i.e. the getters/setters handle language differences). It's a pretty slick system if I may say so myself, works very well so far :) Just don't want my hasattr() to blow up in my face at some unfortunate time! Ah well, whatever it is, it's working ... I suppose I just don't understand why ... But this isn't a Zope problem I guess :) Thanks! J.F. -----Original Message- From: Paul Winkler [mailto:[EMAIL PROTECTED] Sent: October 5, 2005 3:28 PM To: [EMAIL PROTECTED]; zope@zope.org Subject: Re: [Zope] Re: Problem with hasattr() and Zope 2.8.1 >> for propertyname in [ propname for propname in >> self.__multilingualproperties__.keys() if >> self.__multilingualproperties__[propname][1] == True ]: >> attname = '__' + propertyname + '_' + lang >> if hasattr(self, attname): delattr(self, attname) >> >> As you see on the last line, I'm doing a hasattr() on an attribute >> who's name starts with 2 underscores, and it works fine in this case >> (has been for weeks, if not months). > > But do those names *end* with underscores as well? (snip) Oops, sent too quickly; actually it looks to me like they don't (unless lang ends in "__"). However, it's not clear what "it works" means. Your code above won't raise any exceptions, but it shouldn't delete any attributes either :-) >>> class Foo: def __init__(self): self.__blech = 1 self.__blah__ = 1 self._bloop = 1 def do(self): print hasattr(self, "__blech") print hasattr(self, "_Foo__blech") print hasattr(self, "__blah__") print hasattr(self, "_bloop") >>> x = Foo() >>> x.do() False True True True -- Paul Winkler http://www.slinkp.com ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Re: Problem with hasattr() and Zope 2.8.1
>> for propertyname in [ propname for propname in >> self.__multilingualproperties__.keys() if >> self.__multilingualproperties__[propname][1] == True ]: >> attname = '__' + propertyname + '_' + lang >> if hasattr(self, attname): delattr(self, attname) >> >> As you see on the last line, I'm doing a hasattr() on an attribute >> who's name starts with 2 underscores, and it works fine in this case >> (has been for weeks, if not months). > > But do those names *end* with underscores as well? (snip) Oops, sent too quickly; actually it looks to me like they don't (unless lang ends in "__"). However, it's not clear what "it works" means. Your code above won't raise any exceptions, but it shouldn't delete any attributes either :-) >>> class Foo: def __init__(self): self.__blech = 1 self.__blah__ = 1 self._bloop = 1 def do(self): print hasattr(self, "__blech") print hasattr(self, "_Foo__blech") print hasattr(self, "__blah__") print hasattr(self, "_bloop") >>> x = Foo() >>> x.do() False True True True -- Paul Winkler http://www.slinkp.com ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Re: [Zope] Re: Problem with hasattr() and Zope 2.8.1
Doyon, Jean-Francois said: > But then, why does this code work ok? > > class CrosslingualSupport: > """ Mix-in class to provide content objects with support for > cross-lingual properties when needed. > """ > > def clearCrosslingualAttributes(self, lang): > """ For a given language, remove all internal attributes related > to > it. """ > for propertyname in [ propname for propname in > self.__multilingualproperties__.keys() if > self.__multilingualproperties__[propname][1] == True ]: > attname = '__' + propertyname + '_' + lang > if hasattr(self, attname): delattr(self, attname) > > As you see on the last line, I'm doing a hasattr() on an attribute who's > name starts with 2 underscores, and it works fine in this case (has been > for weeks, if not months). But do those names *end* with underscores as well? If so, Python doesn't mangle those names. See: http://docs.python.org/ref/atom-identifiers.html Also, what do you intend to communicate by naming __multilingualproperties__ with the leading and trailing underscores? Might want to read the style guide at http://www.python.org/peps/pep-0008.html if you haven't lately... see the "Naming Conventions" section. -- Paul Winkler http://www.slinkp.com ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
[Zope] Re: Problem with hasattr() and Zope 2.8.1
Alec, Heh, thanks for the reply, I somehow have been using python for a few years now without ever running into that! I'm afraid I'm still baffled by it, mostly because I've used attributes named in such a manner up until now without problem ... >From what you're saying I guess hasattr() being a built-in function, it's not recognized as part of the instance, so the mangling doesn't work right? But then, why does this code work ok? class CrosslingualSupport: """ Mix-in class to provide content objects with support for cross-lingual properties when needed. """ def clearCrosslingualAttributes(self, lang): """ For a given language, remove all internal attributes related to it. """ for propertyname in [ propname for propname in self.__multilingualproperties__.keys() if self.__multilingualproperties__[propname][1] == True ]: attname = '__' + propertyname + '_' + lang if hasattr(self, attname): delattr(self, attname) As you see on the last line, I'm doing a hasattr() on an attribute who's name starts with 2 underscores, and it works fine in this case (has been for weeks, if not months). BUT, in my other situation, it isn't!! Heck, I think I even tried getattr(self, '__attribute') and it didn't work right. ONLY self.__attribute seems to work. But then, I'm back to wondering why the above works fine, and worry that something's going to come bite me later ... I'm starting to wonder if subclassing and/or my usage of metaclasses might be a cause for the different behavior?? Either that, or there's something buggy with zope's versions of get/set/has/delattr ... Even though I've gotten around it, I'll keep looking, it's driving me nuts :) J.F. On Friday 30 September 2005 12:49 pm, Doyon, Jean-Francois wrote: > Hello, > > I'm using new-style classes and properties to implement multilingual > support in my objects. I might therefore have something like: > > mything = property(__get_mything) > > def __get_mything: > return self.__mything_en > > (Extremely simplified!) > > This works fine. > > Now however I'm discovering that doing a hasattr() on anything that starts > with 2 underscores always returns false! > > So hasattr(self, '__thumbnail') doesn't work as expected, but hasattr(self, > '_thumbnail') DOES! (All other things being equal of course). This is actually a feature of python. Names starting with '__' are mangled by the interpreter so that they are not directly accessible outside the class itself; it is an attempt to simulate private class members. If you are finding yourself in need of using a variable that someone else has decided needed to be named with '__' then you may want to rethink what you are doing. It is somewhat rare that a python programmer would use this trick, so you should probably heed the warning and avoid using it if at all possible. If these are methods that you created then just rename them to use a single or preferably no underscores if you need to use them from outside the class itself (a single underscore is still bad form, as '_' is an indicator that a variable is intended to be private and a suggestion that it only be used in the class itself). Alec Mitchell ___ Zope maillist - Zope zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev ) ___ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )