[Tutor] question about descriptors

Alan Gauld alan.gauld at btinternet.com
Sat Nov 7 08:31:34 EST 2015


On 07/11/15 12:53, Albert-Jan Roskam wrote:
> Ok, now to my question.
 > I want to create a class with read-only attribute access
> to the columns of a .csv file.

Can you clarify what you mean by that?
The csvreader is by definition read only.
So is it the in-memory  model that you want read-only?
Except you don't really have an in-memory model that I can see?

> E.g. when a file has a column named 'a', that column should
 > be returned as list by using instance.a.

That appears to be a separate issue to whether the returned
list is read-only or not? As ever the issue of dynamically
naming variables at run time and then figuring out how to
access them later raises its head. Its hardly ever a good plan.

> At first I thought I could do this with the builtin 'property'
 > class, but I am not sure how.

To use property I think you'd need to know the names of your
columns in advance. (Or dynamically build your classes)

> I now tried to use descriptors (__get__ and __set__),
> which are also used by ' property'

> In the " if __name__ == '__main__'" section, [a] is supposed
 > to be a shorthand for == equivalent to [b].

I have no idea what you mean by that sentence?

> class AttrAccess(object):
>
>      def __init__(self, fileObj):
>          self.__reader = csv.reader(fileObj, delimiter=";")
>          self.__header = self.__reader.next()
>      @property
>      def header(self):
>          return self.__header
>
>      def __get_column(self, name):
>          return [record[self.header.index(name)] for record in self.__reader]  # generator expression might be better here.

You should only get the index once otherwise it could add a lot of time 
for a long file(especially if there were a lot of columns)

      def __get_column(self, name):
         idx = self.header.index(name)
         return [record[idx] for record in self.__reader]

>      def __get__(self, obj, objtype=type):
>          print "__get__ called"
>          return self.__get_column(obj)
>          #return getattr(self, obj)
>
>      def __set__(self, obj, val):
>          raise AttributeError("Can't set attribute")

If you want everything read-only should this not be __setattr__()?


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list