I have a python 3.8 routine intended to add typing to a CSV file with headers, as follows:
class Record(NamedTuple):
""" Define the fields and their types in a record. """
Category : str
Item : str
Serving Size : str
Calories : int
SaturatedFat(%pctDaily) : int
Sugars : int
Protein : int
@classmethod
def _transform(cls: 'Record', dct: dict) -> dict:
""" Convert string values in given dictionary to corresponding Record
field type.
"""
return {field: cls._field_types[field](value)
for field, value in dct.items()}
What I've discovered is that any header field containing spaces or special characters will error out with eg,
Saturated(%Fat) : float
^
SyntaxError: invalid syntax
Any ideas how to solve this? TIA, Alex
You're trying to create a NamedTuple
with illegal field names. Quote from the documentation for NamedTuple
:
Any valid Python identifier may be used for a fieldname except for names starting with an underscore. Valid identifiers consist of letters, digits, and underscores but do not start with a digit or underscore and cannot be a keyword such as class, for, return, global, pass, or raise.
Do you need all the trappings of the NamedTuple
? From what I see, having a custom dict-like will work well for you:
class Record:
def __init__(self, record):
self._fields = {}
for k, t in {
"Category": str,
"Saturated(%Fat)": float
}.items():
self._fields[k] = t(record[k])
def __getitem__(self, key):
return self._fields[key]
Note how the constructor knows which fields must be there. Use it like this:
record = Record({"Category": "foo", "Saturated(%Fat)": "5.5"})
record["Saturated(%Fat)"] # 5.5
This is a barebones solution and you may want to add other methods like __len__()
or items()
. Check out Emulating Container Types for your options.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.