basically I've got a booking class with fields each declared manually. I am curious if theres a more neat solution for the given task.
class Booking:
def __init__(self, json_data):
self.referenceNumber = json_data["referenceNumber"]
self.fromDate = json_data["fromDate"]
self.preferredDate1 = json_data["preferredDate1"]
self.preferredTimeFrom = json_data["preferredTimeFrom"]
self.time = json_data["time"]
self.partySize = json_data["partySize"]
self.budgetAmountTotal = json_data["budgetAmountTotal"]
self.budgetAmountPerPerson = json_data["budgetAmountPerPerson"]
self.budgetCurrencySign = json_data["budgetCurrencySign"]
self.venueName = json_data["venueName"]
self.venueId = json_data["venueId"]
self.cityName = json_data["cityName"]
self.clientName = json_data["clientName"]
self.clientContactName = json_data["clientContactName"]
self.status = json_data["status"]
self.statusText = json_data["statusText"]
self.assigneeId = json_data["assigneeId"]
self.assignee = json_data["assignee"]
self.lastAction = json_data["lastAction"]
self.inquiryChannel = json_data["inquiryChannel"]
self.venueDateFormat = json_data["venueDateFormat"]
self.bookingId = json_data["bookingId"]
self.inquiryHold = json_data["inquiryHold"]
self.isSpaceSelectedForHolds = json_data["isSpaceSelectedForHolds"]
self.id = json_data["id"]
bonus if i am not given an unresolved reference warning when I am calling for the attribute.
CodePudding user response:
A simple self.__dict__.update(json_data)
might do the trick.
CodePudding user response:
Given the code in the question, access to attributes would be, for example, in the style of:
Booking().fromDate
However, if you don't mind accessing the value by its key name then you can greatly simplify the code as follows:
class Booking:
def __init__(self, json_data):
self._json = json.data
def __getitem__(self, key):
return self._json.get(key)
Then (for example)...
pd = {'fromDate': '2022/10/18'}
print(Booking(pd)['fromDate'])
CodePudding user response:
How about this?
def set_attr_from_json(obj, json_data):
for key, value in json_data.items():
setattr(obj, key, value)
class Booking:
def __init__(self, json_data):
set_attr_from_json(self, json_data)
CodePudding user response:
Since you want to control how your class attributes should be built, I think you should use metaclass
like this
import json
from types import SimpleNamespace
class BookingMeta(type):
def __call__(self, json_data):
obj = super().__call__(json_data)
obj = json.loads(json.dumps(json_data), object_hook=lambda d: SimpleNamespace(**d))
return obj
class Booking(metaclass=BookingMeta):
def __init__(self, json_data):
pass
b = Booking({"name": {"first_name": "hello", "last_name": "world"}, "age": 23, "sub": ["maths", "Science"]})
print(b.name.first_name)
print(b.age)
#hello
#23