Создание namedtuple, действительного для разных параметров - PullRequest
0 голосов
/ 18 июня 2019

Я пытаюсь найти способ создать именованный кортеж с переменными полями в зависимости от данных, которые вы получаете , в моем случае я использую данные из StatCounter и не во всех периодах одинаковые браузеры.Я пробовал этот способ, но это немного уродливо, и я уверен, что есть лучший способ добиться этого.

def namedtuple_fixed(name: str, fields: List[str]) -> namedtuple:
    """Checks the fields of the namedtuple and changes the invalid ones."""

    def starts_with_number(string: str) -> bool:
        if string[0].isdigit():
            return True
        return False

    fields_fixed: List[str] = [
        field.replace(" ", "_")
        if not starts_with_number(field)
        else f"c{field.replace(' ', '_')}"
        for field in fields
    ]

    return namedtuple(name, fields_fixed)


Records: namedtuple = None


def read_file(file: str) -> List["Records"]:
    """
    Read the file with info about the percentage of use of various browsers
    """
    global Records

    with open(file, encoding="UTF-8") as browsers_file:
        reader: Iterator[List[str]] = csv.reader(browsers_file)
        field_names: List[str] = next(reader)
        Records = namedtuple_fixed("Record", field_names)
        result: List[Records] = [
            Records(
                *[
                    dt.datetime.strptime(n, "%Y-%m").date()
                    if record.index(n) == 0
                    else float(n)
                    for n in record
                ]
            )
            for record in reader
        ]
    return result

Функция "namedtuple_fixed" заключается в исправлении имен, которые имеют недопустимые идентификаторы.

По сути, я хочу создать именованный кортеж, который получает переменное число параметров , в зависимости от файла, который вы хотите проанализировать.И если это с включенной проверкой типов (я имею в виду использование NamedTuple из модуля ввода), то гораздо лучше.Заранее спасибо.

1 Ответ

0 голосов
/ 18 июня 2019

Это решает мою проблему, но линтеры, такие как pylint или mypy, не распознают метод dict , и если я пытаюсь получить элемент, он предупреждает меня, что у него нет этого атрибута,даже если он у него есть


class Record:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

    def __repr__(self):
        keys = sorted(self.__dict__)
        items = [f"{k}={self.__dict__[k]!r}" for k in keys]
        return f"Record({', '.join(items)})"

    def __eq__(self, other):
        return self.__dict__ == other.__dict__

Это был переработанный код из types.SimpleSpace Документация

...