0
class Name(NamedTuple):
    first_name: str
    last_name: str

name: Name = Name(first_name="Guido", last_name="Rossum")

updated = {**name._asdict()}

updated.update({"last_name": "Fox"})

updated_name: Name = Name(**updated)

I am aware the nature of tuples is meant to be immutable, but I can't think of any data objects which provide the conciseness of a NamedTuple.

(For example, if I want to define the keys and values of a JSON object, I can simply define the attributes as shown in Name)

But let's say I need to update an attribute before I save to database, then being able to do that in a single line would be useful.

creampiedonut
  • 327
  • 1
  • 5
  • 17
  • You are not updating, you are creating new object. – BJT Aug 14 '18 at 12:31
  • Have you tried this: https://docs.python.org/3/library/collections.html#collections.somenamedtuple._replace – BJT Aug 14 '18 at 12:55
  • @josip No I haven't but I thought underscore are meant to be private? (not good practice?) – creampiedonut Aug 14 '18 at 13:26
  • yes it should not be called from outside the class instance, but if the docs say you can...i would use custom class to solve your problem. – BJT Aug 14 '18 at 14:35
  • The `_` in front of replace is to avoid name collisions, so you can use `replace` as a key if you wanted to ("To prevent conflicts with field names, the method and attribute names start with an underscore", see [here](https://docs.python.org/3/library/collections.html#collections.namedtuple)). Feel free to call it, that's why it's there. (I won't make this an answer because I don't understand what you're trying to do with your subclassing.) – DSM Aug 14 '18 at 14:59

1 Answers1

0

I think it is better to create custom class to store the data, i would do it like this:

class Name:
  # use slots
  # https://docs.python.org/3/reference/datamodel.html#slots
  # https://stackoverflow.com/questions/472000/usage-of-slots
  __slots__ = ('first_name', 'last_name')

  def __init__(self, first_name, last_name):
    self.first_name = first_name
    self.last_name = last_name

  def __repr__(self):
    return "{} {}".format(self.first_name, self.last_name)

name: Name = Name('Guido', 'Van Rossum')
print(name)

name.last_name = 'Fox'
print(name)
BJT
  • 648
  • 5
  • 16