Обновление поля в NamedTuple (от ввода) - PullRequest
0 голосов
/ 28 сентября 2018

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

#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-

from typing import NamedTuple

class Template (NamedTuple):
    number : int = 0
    name : str = "^NAME^"

oneInstance = Template()
print(oneInstance)
# If I know the variable name during development, I can do this:
oneInstance = oneInstance._replace(number = 77)
# I get this from a file during runtime:
para = {'name' : 'Jones'}
mykey = 'name'
# Therefore, I used exec:
ExpToEval = "oneInstance = oneInstance._replace(" + mykey + " = para[mykey])"
exec(ExpToEval) # How can I do this in a more pythonic (and secure) way?
print(oneInstance)

Я думаю, с 3.7 я мог бы решить эту проблему с помощью классов данных, но мне нужно за 3,6

1 Ответ

0 голосов
/ 28 сентября 2018

Использование _replace в именованных кортежах нельзя сделать "питоническим".Namedtuples должны быть неизменными.Если вы используете именованный кортеж, другие разработчики будут ожидать, что вы не собираетесь изменять ваши данные.

Питонический подход - это действительно класс данных .Вы также можете использовать классы данных в Python3.6 .Просто используйте бэкпорт классов данных из PyPi .

Тогда все становится действительно читабельным, и вы можете использовать getattr и setattr для простой адресации свойств по имени:

from dataclasses import dataclass

@dataclass
class Template:
    number: int = 0
    name: str = "^Name^"

t = Template()

# use setattr and getattr to access a property by a runtime-defined name  
setattr(t, "name", "foo")
print(getattr(t, "name"))

Это приведет к

foo
...