Package: lightcsv
LightCSVSimple light CSV readerThis CSV reader is implemented in just pure Python. It allows to specify a separator, a quote char and
column titles (or get the first row as titles). Nothing more, nothing else.UsageUsage is pretty straightforward:fromlightcsvimportLightCSVforrowinLightCSV().read_file("myfile.csv"):print(row)This will open a file namedmyfile.csvand iterate over the CSV file returning each
row as a key-value dictionary. Line endings can be either\nor\r\n. The file will be opened
in text-mode withutf-8encoding.You can supply your own stream (i.e. an open file instead of a filename). You can use this, for example,
to open a file with a different encoding, etc.:fromlightcsvimportLightCSVwithopen("myfile.csv")asf:forrowinLightCSV().read(f):print(row)NOTE: Blank lines at any point in the file will be ignoredParametersLightCSV can be parametrized during initialization to fine-tune its behaviour.The following example shows initialization with default parameters:fromlightcsvimportLightCSVmyCSV_reader=LightCSV(separator=",",quote_char='"',field_names=None,strict=True,has_headers=False)Available settings:separator: character used as separator (defaults to,)quote_char: character used to quote strings (defaults to").This char can be escaped by duplicating it.field_names: can be any iterable or sequence ofstr(i.e. a list of strings).If set, these will be used as column titles (dictionary keys), and also sets the expected number of columns.strict: Sets whether the parser runs instrict modeor not.Instrict modethe parser will raise aValueErrorexception if a cell cannot be decoded or column
numbers don't match. Innon-strict modenon-recognized cells will be returned as strings. If there are more
columns than expected they will be ignored. If there are less, the dictionary will contain also fewer values.has_headers: whether the first row should be taken as column titles or not.If set,field_namescannot be specified. If not set, and no field names are specified, dictionary keys will
be just the column positions of the cells.Data types recognizedThe parser will try to match the following types are recognized in this order:None(empty values). Unlike CSV reader, it will returnNone(null) for empty values.Empty strings ("") are recognized correctly.str(strings): Anything that is quoted with thequotechar. Default quotechar is".If the string contains a quote, it must be escaped duplicating it. i.e."HELLO ""WORLD"""decodes
toHELLO "WORLD"string.int(integers): an integer with a preceding optional sign.float: any float recognized by Pythondatetime: a datetime in ISO format (with 'T' or whitespace in the middle), like2022-02-02 22:02:02date: a date in ISO format, like2022-02-02time: a time in ISO format, like22:02:02If all this parsing attempts fails, a string will be returned, unlessstrict_modeis set toTrue. In the latter
case, aValueErrorexception will be raised.Implementing your own type recognizerYou can implement your own deserialization by subclassingLightCSVand override the methodparse_obj().For example, suppose we want to recognize hexadecimal integers in the format0xNNN.... We can implement it
this way:importrefromlightcsvimportLightCSVRE_HEXA=re.compile('0[xX][A-Za-z0-9]+$')# matches 0xNNNN (hexadecimals)classCSVHexRecognizer(LightCSV):defparse_obj(self,lineno:int,chunk:str):ifRE_HEXA.match(chunk):returnint(chunk[2:],16)returnsuper().parse_obj(lineno,chunk)As you can see, you have to overrideparse_obj(). If your match fails, you have to invokesuper()(overridden)parse_obj()method and return its result.WhyPython built-in CSV module is a bit over-engineered for simple tasks, and one normally doesn't need all bells
and whistles. WithLightCSVyou just open a filename and iterate over its rows.DecodingNonefor empty cells is needed very often and can be really cumbersome as the standardcsvtries hard to cover many corner-cases (if that's your case, this tool might not be suitable for you).