I am trying to parse a json MSG into a python dict.
For reference, the message is received from the Things Network with the python MQTT handler.
Here is the format I am receiving when I print the object
msg = MSG(variable_group=MSG(data0=0, data1=0, data2=0), variable2='name', variable3='num')
In its default state, I can access individual fields by msg.variable2 for example which provides 'name' but does not provide the variable name itself.
This is fine for a scenario in which I hardcode everything into my system, but I would like it to be a bit more adaptable and create new entries for variables as they come in.
Is there any way to parse this in such a way that I get both the data and the variable name?
Thanks!
EDIT:
From the input above, I would like to get a python dict containing the variable name and data.
dict =
{
variable_group : MSG(data0=0, data1=0, data2=0),
variable2 : 'name',
variable3 : 'num'
}
Currently, I can access the data via a for loop and can print the variable names if I print the entire structure, but cannot access the variable names through a looping mechanism
EDIT 2:
After doing some digging on the wrapper found the following:
def _json_object_hook(d):
return namedtuple("MSG", d.keys())(*d.values())
def json2obj(data):
return json.loads(data, object_hook=_json_object_hook)
Where the input shown above is created by passing it as 'data' to json2obj.
I am still unsure how to get a dict out of this format, haven't used object_hooks before.
From discussion in the comments below, it appears that the MSG object is a namedtuple created on the fly out of the json object.
In a case like that you can get the fields by looking at the _fields of the object. You can dict-ify a namedtuple like this
def nt_to_dict(nt):
return {field, getattr(nt, field) for field in nt._fields}
or you could just inspect the object by trolling _fields in code and using getattr as needed
Related
I am trying to serialize a list of objects.
I am making an HTTP API call. The call returns a list of objects (e.g. class A). I do not have access to the definition of class A.
I tried using dumps
print ("Result is: %s", json.dumps(result_list.__dict__))
This prints an empty result. However if I were to print the result_list I get below output
{
"ResultList": [{
"fieldA": 0,
"fieldB": 1.46903594E9,
"fieldC": "builder",
"fieldD": "StringA/StringB-Test-124.35.4.24"
}]
}
IS there a way I can convert the object with whichever field it returns to a json.
Please specify more how the class of which result_list is an instance looks like (e.g. post the class code).
json.dumps(result_list) probably works not since result_list is not a plain dictionary, but an object of a class. You need to dump the variable that holds the data structure (i.e. the same that is displayed in the print call).
When reading the simple-salesforce docs, it only shows accessing object metadata using hard-coded methods like such:
sf.Contact.metadata()
Is there no way to do something like this?
sf["Contact"].metadata()
I want to loop through a list of objects and retrieve all these objects fields, but it seems like this isn't possible due to the limitation seen above.
for obj in objects:
fields = [x["name"] for x in sf[obj].describe()["fields"]]
# processing for each object
Is there any way to access object metadata using a string parameter, instead of a hard-coded value?
The sf. interface is actually call to the the get_attr method in the Salesforce class.
get_attr returns the value of SFType(name, self.session_id, self.sf_instance, self.sf_version, self.proxies).
You could do what you would like with the following:
from simple_salesforce import SFType
....
sf_object = ['Case', 'Contact', 'Account', 'Custom1__c', 'Custom2__c']
for each in sf_object:
SFType(each, sf.session_id, sf.sf_instance, sf.sf_version, sf.proxies).metadata()
Hope that helps.
Here's my setup: dictD contains a key users paired with value = list of UserObjects. Each UserObject has an attribute username plus two arrays, threads and comments.
I was able to convert dictD's array of user objects into a dictionary style with this call:
dictD["users"] = [user.__dict__ for user in dictD["users"]]
If I dump out dictD, here's the relevant part before I try to do my manipulation:
{
'users':[
{
'username': Redditor(user_name='$$$$$$$$$$'),
'threads':[
<__main__.redditThread instance at 0x7f05db28b320>
],
'comments':[
<__main__.comment instance at 0x7f05db278e60>
]
},
{
'username': Redditor(user_name='##########e\ gone'),
'threads':[
<__main__.redditThread instance at 0x7f05db2a4a70>
],
'comments':[
<__main__.comment instance at 0x7f05db298e18>
]
}
As you can see the comments contain comment objects and the threads list contains thread objects. So I'd like to do the same call for them that I did for the users array. But when I try to do this:
for user in dictD["users"]:
user.threads = [thread.__dict__ for thread in user.threads]
user.comments = [comment.__dict__ for comment in user.comments]
I run into this error:
AttributeError: 'dict' object has no attribute 'threads'
I also tried
users = dictD["users"]
for user in users...
but this triggers the same error message. How can I turn objects in lists into dictionary form when those objects' lists are themselves held within objects within lists within a dictionary?
Incidentally, I am doing all this so I can insert these objects into MongoDB, so if there is an easier way to serialize a complex object, please let me into the secret. Thank you.
Promoting my comment to an answer since it seems reasonable and nobody else is posting: it looks at a glance like you're confusing Python for Javascript: a dict with a key 'threads' is not an object you can reference with .threads, only with ["threads"]. ie. user.threads should be user["threads"]. A dict usually only has the same standard attributes (see: https://docs.python.org/2/library/stdtypes.html#typesmapping or https://docs.python.org/3/library/stdtypes.html#mapping-types-dict for Python 3.) The problem isn't that you're trying to call __dict__ on an object, it's that you're trying to get an attribute from an object that doesn't exist, later in that same line of code.
If you want to recreate complex objects from MongoDB rather than just nested dicts and lists then that is basically a process of deserialization; you can either handle that manually, or maybe use some sort of object mapping library to do it for you (eg. something like Mongoobject might work, though I've not tested it myself)
I've looked at documentation, and have searched Google extensively, and haven't found a solution to my problem.
This is my readRSS function (note that 'get' is a method of Kenneth Reitz's requests module):
def readRSS(name, loc):
linkList = []
linkTitles = list(ElementTree.fromstring(get(loc).content).iter('title'))
linkLocs = list(ElementTree.fromstring(get(loc).content).iter('link'))
for title, loc in zip(linkTitles, linkLocs):
linkList.append((title.text, loc.text))
return {name: linkList}
This is one of my MongoAlchemy classes:
class Feed(db.Document):
feedname = db.StringField(max_length=80)
location = db.StringField(max_length=240)
lastupdated = datetime.utcnow()
def __dict__(self):
return readRSS(self.feedname, self.location)
As you can see, I had to call the readRSS function within a function of the class, so I could pass self, because it's dependent on the fields feedname and location.
I want to know if there's a different way of doing this, so I can save the readRSS return value to a field in the Feed document. I've tried assigning the readRSS function's return value to a variable within the function __dict__ -- that didn't work either.
I have the functionality working in my app, but I want to save the results to the Document to lessen the load on the server (the one I am getting my RSS feed from).
Is there a way of doing what I intend to do or am I going about this all wrong?
I found out the answer. I needed to make use of a computed_field decorator, where the first argument was the structure of my return value and deps was a set which contained the fields that this field was dependent on. I then passed the dependent fields into a function's arguments and there you have it.
#fields.computed_field(db.KVField(db.StringField(), db.ListField(db.TupleField(db.StringField()))), deps=[feedname, location])
def getFeedContent(a=[feedname, location]):
return readRSS(a['feedname'], a['location'])
Thanks anyway, everyone.
Is there a way or a library made to deserialize a JSON string into a typed object in ActionScript and Python?
For eg.
class Person
{
String name;
int age;
}
Person person = new Person("John", "22");
String jsonString = JSON.Serialize(person);
Person person2 = (Person) JSON.Deserialize(jsonString);
So, the last statement basically casts the object we get after deserializing the jsonString into the Person object.
I can only speak for Python. There is a built in library for JSON access, it can be viewed in the docs here.
Unfortunately, out of the box, you cannot serialize/deserialize objects, just dicts, lists and simply types. You have to write specific object encoders to do so. This is pretty much covered in the docs.
For AS3 you can use as3corelib by Mike Chambers.
https://github.com/mikechambers/as3corelib/tree/master/src/com/adobe/serialization/json
Edit: After some Googling I ended up back on SO at this question: Typed AS3 JSON Encoder and Decoder? It seems that there is a library for doing typed deserialization, but it is not totally robust and fails on some data types. If you think you can handle the restrictions then it might be the best option short of writing your own parser or gettting into something heavy like BlazeDS.
http://code.google.com/p/ason/
Please try with this:
import json
class Serializer:
#staticmethod
def encode_obj(obj):
if type(obj).__name__ =='instance':
return obj.__dict__
#staticmethod
def serialize(obj):
return json.dumps(obj, default=Serializer.encode_obj)
class TestClass:
def __init__(self):
self.a = 1
t = TestClass()
json_str = Serializer.serialize(t)
Short answer: No there is not. JSON doesn't include typed objects except for a few such as Arrays. The as3Corelib does recognize these. But as you mentioned, you get back an Object with name value pairs. Since JSON does not contain your custom actionscript classes, there is no automatic way to convert a JSON object into a typed actionscript object.
The as3corelib is a great utility for JSON in flash. However the latest build of the flash player (version 10.3) includes JSON as a native data type.
But it is not very difficult to create a class with a constructor that takes the JSON object as an argument, and you can parse it into the class variables. I have to do this all the time when working with the facebook Graph API.