简体   繁体   中英

Python type definitions with space or special chars

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM