comparing dialects of csv-module

Peter Otten __peter__ at web.de
Sat Dec 19 09:06:58 EST 2009


Malte Dik wrote:

> Hi out there!
> 
> I want to put some intelligence into a csv reading script and in order to
> do so I want to compare possible different dialects I collect with some
> random
> 
> d = csv.Sniffer().sniff("1,2,3,4"),
> 
> because the csv is kinda dirty.
> 
> Now sniff() returns a class object and those aren't comparable in the "if
> dialect_1 == dialect_2: count something" sense.
> 
> Has anyone around here already dealt with this kind of problem and maybe
> even a solution I could utilize? That would be great.

An implementation for the lazy

>>> import csv
>>> d = csv.Sniffer().sniff("1,2,3")
>>> def eq(a, b, attributes=[name for name in dir(d) if not 
name.startswith("_")]):
...     return all(getattr(a, n, None) == getattr(b, n, None) for n in 
attributes)
...
>>> eq(d, csv.Sniffer().sniff("3,4,5"))
True
>>> eq(d, csv.Sniffer().sniff("'3','4','5'"))
False
>>> eq(d, csv.Sniffer().sniff("3;4;5"))
False
>>> eq(d, csv.Sniffer().sniff("3,4,' 5'"))
True

 
> If not - I guess I would just write a quick function comparing the
> attributes of those dialects ... - but just out of educational curiosity:
> Would it be the right way to implement an __eq__(...) function into the
> Dialect class or how would someone who would want to make it right do it?

I don't know if you can do it for classic classes; for newstyle classes 
you'd have to reimplement comparison in the metaclass:

>>> class Dialect:
...     class __metaclass__(type):
...             def __eq__(self, other):
...                     return self._key() == other._key()
...             def __ne__(self, other):
...                     return self._key() != other._key()
...             def _key(self):
...                     return self.quotechar, self.delimiter #,...
...
>>> class A(Dialect):
...     quotechar = "'"
...     delimiter = ":"
...
>>> class B(Dialect):
...     quotechar = "'"
...     delimiter = ","
...
>>> A == B
False
>>> B.delimiter = ":"
>>> A == B
True

On a side note, I think it's a C++ism that dialects are classes rather than 
class instances. That's a superfluous complication since in Python no work 
will be moved from compile time to runtime anyway.

Peter



More information about the Python-list mailing list