I'd like to update a field within a dataclass, but I know the field name only during runtime, not during development time.
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
from dataclasses import dataclass # I use the backport to 3.6
@dataclass
class Template:
number: int = 0
name: str = "^NAME^"
oneInstance = Template()
print(oneInstance) # Template(number=0, name='^NAME^')
# If I know the variable name during development, I can do this:
oneInstance.number=77
# I get this from a file during runtime:
para = {'name': 'Jones'}
mykey = 'name'
# Therefore, I used exec:
ExpToEval = "oneInstance." + mykey + ' = "' + para[mykey] + '"'
print (ExpToEval) # oneInstance.name = "Jones"
exec(ExpToEval) # How can I do this in a more pythonic (and secure) way?
print(oneInstance) # Template(number=77, name='Jones')
I need something like
oneInstance[mykey] = para[mykey]
but this ends up in "TypeError: 'Template' object does not support item assignment"
You can try replace() method, like below:
from dataclasses import dataclass, replace
@dataclass
class Template:
number: int = 0
name: str = "^NAME^"
oneInstance = Template()
print(oneInstance)
para = {'name': 'Jones'}
oneInstance = replace(oneInstance, **para)
print(oneInstance)
That should do the job if your dict para
only contains keys that are fields of your dataclass.
You can use setattr to update an object's attributes during runtime:
oneInstance = Template()
setattr(oneInstance, 'name', 'Jones') # this doesn't raise a TypeError
print(oneInstance.name) # prints: 'Jones'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With