i want to create an object of My_Class and want to tell it with a string what dictionary to get. Is there a better way than to do it with if?
object_dictionary = {
"car" : "some_car",
"house" : "some_house",
"animal" : "some_animal"
}
class My_Class:
def __init__(self, string):
if string == "object_dictionary":
self.dictionary = object_dictionary
obj = My_Class("object_dictionary")
If I want to choose between more dictionaries this will be inconvenient. How can I do this?
object_dictionary = {
"car" : "some_car",
"house" : "some_house",
"animal" : "some_animal"
}
class My_Class:
def __init__(self, string):
self.dictionary = string
obj = My_Class("object_dictionary")
Use dict of dicts. See below
dicts = {
"this_dictionary": {
"car": "some_car",
"house": "some_house",
"animal": "some_animal"
},
"that_dictionary": {
"12": "ttt"
}
}
class MyClass:
def __init__(self, dict_name):
self.dictionary = dicts.get(dict_name, {})
obj = MyClass("that_dictionary")
Related
I have an API response that can respond with an array like this:
[
{
"id": 1,
"title": "Warning"
},
{
"id": 2,
"title": "Warning"
}
]
sometimes it can respond just empty array
[]
in my case i created a class for this object.
Something like this:
class Warning:
def __init__(self, data: Dict):
if bool(data):
self.id: int = data["id"]
self.title: str = data["title"]
else:
pass
if __name__ == '__main__':
data = {
"id": 123455,
"title": "Warning"
}
empty_data = {}
object1: List[Warning] = [Warning(data)]
object2: List[Warning] = [Warning(empty_data)]
if object1:
print("we have a warnings")
if object2:
print("we don't have warnings")
I can't understand, how can I check if i get List of Object with empty fields like object2?
I would suggest looking at the __bool__ class method which enables you to determine the boolean value of a python class.
However, you will also need to decide what the boolean value of the list should be e.g. should bool([Warning(empty_data), Warning(data)]) return False or True?
I need convert one file XML to JSON with python, but I need put the attributes of the father after the child nodes in the JSON
My current code is like that.
def generate_json(self, event=None):
# opening the xml file
with open(self.fn ,"r") as xmlfileObj:
data_dict = lib.xmltodict.parse(xmlfileObj.read(),attr_prefix='_')
xmlfileObj.close()
jsonObj= json.dumps(data_dict, sort_keys=False)
restored = json.loads(jsonObj)
#storing json data to json file
with open("data.json", "w") as jsonfileObj:
jsonfileObj.write(jsonObj)
jsonfileObj.close()
and I need this;
{
"datasetVersion": {
"metadataBlocks": {
"citation": {
"fields": [
{
"value": "Darwin's Finches",
"typeClass": "primitive",
"multiple": false,
"typeName": "title"
}
],
"displayName": "Citation Metadata"
}
}
}
}
in place of:
{
"datasetVersion": {
"metadataBlocks": {
"citation": {
"displayName": "Citation Metadata",
"fields": [
{
"value": "Darwin's Finches",
"typeClass": "primitive",
"multiple": false,
"typeName": "title"
}
]
}
}
}
}
No in alphabetic order changing sort_keys=False, I need only to change the attributes of node father to the final.
on some website make how I need:
https://www.convertjson.com/xml-to-json.htm
and another no how:
http://www.utilities-online.info/xmltojson/#.X_crINhKiUk
can somebody help me?
I could format making use of the https://pypi.org/project/xmljson/ library, I modified the BadgerFish style
class BadgerFish(XMLData): # the convention was changed from the project the prefix _ and order the attributers of father nodes
'''Converts between XML and data using the BadgerFish convention'''
def init(self, **kwargs):
super(BadgerFish, self).init(attr_prefix='_', text_content='$', **kwargs)
I changed the prefix of the attribute to "_"
by otherwise only changed the **# modify to put the father attributes to finish, how we can see in the code
def data(self, root):
'''Convert etree.Element into a dictionary'''
value = self.dict()
children = [node for node in root if isinstance(node.tag, basestring)]
if root.text and self.text_content is not None:
text = root.text
if text.strip():
if self.simple_text and len(children) == len(root.attrib) == 0:
value = self._fromstring(text)
else:
value[self.text_content] = self._fromstring(text)
count = Counter(child.tag for child in children)
for child in children:
# if child.tag == "System_State_Entry": print(child.tag)
if count[child.tag] == 1:
value.update(self.data(child))
else:
result = value.setdefault(child.tag, self.list())
result += self.data(child).values()
# if simple_text, elements with no children nor attrs become '', not {}
if isinstance(value, dict) and not value and self.simple_text:
value = ''
**# modify to put the father atributes to finish
for attr, attrval in root.attrib.items():
attr = attr if self.attr_prefix is None else self.attr_prefix + attr
value[attr] = self._fromstring(attrval)**
return self.dict([(root.tag, value)])
How can I get JSON from nested python object
class simplobj:
def _init_(self,fname,lname,depart):
self.fname=fname
self.lname=lname
self.depart = depart
class jsonobj:
array = []
def _init_(self,time,listOfSimpleObj):
self.time = time
self.array = listofSimpleObj
class Main:
listOfSimpleObj =[]
sobj = simplobj("fname1","lname1","depart1")
listOfSimpleObj.append(sobj)
outputjsonobj = jsonobj(time,listOfSimpleObj)
output = json.dumps(outputjsonobj._dict_)
output: { "time" : "time", "array": [
{ "fname": "fname1", "lname": "lname1", "depart": "depart1"},
{ "fname": "fname2", "lname": "lname2", "depart": "depart2"},
{ "fname": "fname3", "lname": "lname3", "depart": "depart3"} ] }
You could create a json.JSONEncoder to specify how your classes should be serialized:
class MyEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, simplobj) or isinstance(obj, jsonobj):
return obj.__dict__
return json.JSONEncoder.default(self, obj)
...
output = json.dumps(outputjsonobj, cls=MyEncoder)
I have a class A where it stores a collection of variables of type B, how can I serialize class A to JSON properly?
example:
class A:
def __init__(self):
self.b_collection = []
#...
class B:
def __init__(self):
# ...
pass
and add instances of B into the collection:
a = A()
a.b_collection = [B(), B(), B()]
when I try to serialize a with json.dumps(a) I get this error: Object of type A is not JSON serializable.
Is there a way to specify how to encoder should encode that class?
something like
def __encode__(self, encoder):
encoder.start_obj()
encoder.add_property('name', self.value)
encoder.add_property('age', self.age)
encoder.end_obj()
which would return something like
{
name: 'Tomer',
age: '19'
}
You can extend json.JSONEncoder to define how to serialize your objects. The default method of your subclass will take a Python object as an argument. You can return a new object that is (hopefully) encodable, or pass the object on to the parent in hopes that it knows how to encode the object.
For example,
class A:
def __init__(self):
self.b_collection = []
class B:
def __init__(self, name, age):
self.name = name
self.age = age
class ABEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, A):
return {'__A__': obj.b_collection}
elif isinstance(obj, B):
return {'__B__': obj.__dict__}
return super().default(obj)
a = A()
a.b_collection.append(B("Tomer", "19"))
a.b_collection.append(B("Bob", "21"))
a.b_collection.append(B("Alice", "23"))
print(json.dumps(a, cls=ABEncoder, indent=4))
would produce
{
"__A__": [
{
"__B__": {
"name": "Tomer",
"age": "19"
}
},
{
"__B__": {
"name": "Bob",
"age": "21"
}
},
{
"__B__": {
"name": "Alice",
"age": "23"
}
}
]
}
Note that you can handle A and B separately; you don't have to first encode the B objects before returning the encodable form of A; the B objects will be encoded later when the list itself is encoded.
The extra objects make it easier to write a decoder; you don't have to make it this complicated if you don't want to be able to decode the JSON to an instance of A. Instead, you can just define
class ABEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, A):
return obj.b_collection
elif isinstance(obj, B):
return obj.__dict__
return super().default(obj)
to get
[
{
"name": "Tomer",
"age": "19"
},
{
"name": "Bob",
"age": "21"
},
{
"name": "Alice",
"age": "23"
}
]
Maybe data classes can help:
from dataclasses import asdict, dataclass
from typing import List
import json
#dataclass
class Person:
name: str
age: str
#dataclass
class Group:
persons: List[Person]
data = [
{'name': 'Tomer', 'age': '19'},
{'name': 'Ivan', 'age': '20'}
]
persons = [Person(**person) for person in data]
group = Group(persons=persons)
assert json.dumps(asdict(group)) == '{"persons": [{"name": "Tomer", "age": "19"}, {"name": "Ivan", "age": "20"}]}'
persons = [asdict(person) for person in group.persons]
assert persons == [{"name": "Tomer", "age": "19"}, {"name": "Ivan", "age": "20"}]
assert json.dumps(persons) == '[{"name": "Tomer", "age": "19"}, {"name": "Ivan", "age": "20"}]'
I got a class with arrays of classes as properties
class classToJson():
def __init__(self, name, image, objects1, objects2):
self.name = name
self.image = image
self.boolean = True
self.objects1 = objects1
self.objects2 = objects2
def __repr__(self):
return json.dumps(self.__dict__)
object1 and object2 class looks like this:
class object1():
value1 = 1
value2 = 0
class objects2:
def __init__(self, name, value):
self.name = name
self.value = value
This is how I create my json of the class.
obj2 = [...]
parsedObject = classToJson(name, image, [object1], obj2)
file = open("{}.json".format(name),"w")
file.write("[{}]".format(parsedObject.__repr__()))
file.close()
This works if I only use name, image and boolean in the class but when I include objects1 or objects2 I get the TypeError: Object of type 'type' is not JSON serializable. Why?
The json schema I want to accomplish:
[
{
"name": "name",
"image": "image",
"boolean": true,
"objects1": [
{
"value1": 1,
"value2": 0
}
],
"objetcs2": [
{
"name": "name",
"value": "value"
}
]
}
]
Just use the built in json.dump like so
import json
with open('file.json') as f:
json.dump([{
'name': name,
'image': image,
'boolean": True,
'object1': object1,
'object2': object2
}], f)