![]() |
Home
| Calendar
| Mail Lists
| List Archives
| Desktop SIG
| Hardware Hacking SIG
Wiki | Flickr | PicasaWeb | Video | Maps & Directions | Installfests | Keysignings Linux Cafe | Meeting Notes | Linux Links | Bling | About BLU |
On Mon, 2007-07-30 at 15:46 -0400, Seth Gordon wrote: > Then I set up a client class like this: > > > class Foo(object): > > def __init__(self): > > for attr in ('bar', 'baz', 'quux'): > > self.__dict__[attr] = WriteOnly(attr) > > > > foo = Foo() > > foo.bar = 4 > > foo.baz = None > > print `foo.bar` > > print `foo.baz` > > print `foo.quux` > > Running that program (with Python 2.4.4) gives me this output: > > > 4 > > None > > <WriteOnly.WriteOnly object at 0xf7daa28c> > > Why don't I get "None" on the third line? What subtle (or > not-so-subtle) detail of Python descriptors am I missing? What you've done is to set the attributes Foo.bar, Foo.baz, and Foo.quux to instances of the WriteOnly class. However, because Foo.bar is a reference (just like everything in Python), doing this: foo.bar = 4 overrides the 'bar' attribute of the instance known as foo. It is no longer a 'WriteOnly' instance. If you did a print str(type(foo.bar)), it would report that it is now an instance of an Integer object. Similarly, foo.baz = None is replacing the value of foo.baz (which used to be a 'WriteOnly' instance) with the None object. At this point, foo.quux is an instance of a 'WriteOnly' object and because you're not overriding the __repr__ method, the "'"s are defaulting to the normal behavior. Oh, just as an FYI, I believe the "`" approach is deprecated in deference to calling repr(whatever). What I think you're really trying to to do is to override the __setattr__ and __getattribute__ calls. Warning, code below is untested, but I think you want something like this: class WriteOnly(object): def __init__(self, write_only_attrs): self.__write_only = {} for attr_name in write_only_attrs: self.__write_only[attr_name] = 1 self.__write_once = {} def __setitem__(self, key, value): if self.__write_only.get(key) and self.__write_once.get(key): oldval = self.__write_once.get(key) msg = "Can't reset %s from %s to %s" % (key, oldval, value) raise Attribute Error, msg elif self.__write_only.get(key): return self.__write_once[key] = value else: return self.__dict__[key] = value def __getitem__(self, key): if self.__write_only.get(key): # Note this will throw an exception if you haven't set # it yet return self.__write_once[key] else: # Ditto return self.__dict__[key] class Foo(WriteOnly): def __init__(self): super(Foo, self).__init__(['bar', 'baz', 'quux']) Feel free to ask questions. -- A: Yes. > Q: Are you sure? >> A: Because it reverses the logical flow of conversation. >>> Q: Why is top posting annoying in email? Cole Tuininga colet-KCgK2vT7wad/90uGnh1m2w at public.gmane.org http://www.code-energy.com/ -- This message has been scanned for viruses and dangerous content by MailScanner, and is believed to be clean.
![]() |
|
BLU is a member of BostonUserGroups | |
We also thank MIT for the use of their facilities. |