Drew U
Drew U

Reputation: 483

Class that returns json, python

I have a python class that should return a json, it looks something like this:

class ScanThis():
    def__init__(self, test):
        data={}
        if test>5:
            data["amount"] = test
            self.json_data = json.dumps(data)
        else:
            data["fail"] = test
            self.json_data = json.dumps(data)

    def __str__(self):
        return self.json_data

and I'm trying to call it like so:

output= json.loads(ScanThis(8))
print(output["command"])

But I get this error:

TypeError: the JSON object must be str, bytes or bytearray, not 'ScanThis'

I believe my earlier clas returns an object of type ScanThis() rather than a JSon like I wanted. I just wanted to now how I'd fix this Thank you

PS: I apologise if this code is rough or invalid, it's not the actual code, just something similar I made up

Update: Again, this isn't the real code, it's just a small basic fragment of the actual code. There's a good reason I'm using a class, and a json is used cause data transfer over the internet is involved

Upvotes: 1

Views: 4354

Answers (2)

user3089519
user3089519

Reputation:

I don't think you are wanting to use a class there at all. Instead, try using a function that returns a string. For example:

def scan_this(test):
    data={}
    if test>5:
        data["amount"] = test
        json_data = json.dumps(data)
    else:
        data["fail"] = test
        json_data = json.dumps(data)

    return json_data

output = json.loads(scan_this(8))

However!! Now you are just doing extra work for nothing? Why do you need to serialize a python dictionary as a json formatted string, and then load it back into a python dictionary straight away? While you are working with data in python, it's best to keep it as native data types, and only using the json module to either load from a string/file you already have, or serialize to a string/file for storage or transfer (eg sending over the internet).

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477264

Use str(..)

You can't call json.loads on a ScanThis object directly. So that won't work. Like the error says, json.loads expects a str, bytes or bytearray object.

You can however use str(..) to invoke the __str__(self) method, and thus obtain the JSON data:

output = json.loads(str(ScanThis(8)))
#                   ^ get the __str__ result 

Use another method

That being said, it is usually a better idea to define a method, for instance to_json to obtain the JSON data, since now you have made str(..) return a JSON object. So perhaps a more elegant way to do this is the following:

class ScanThis():
    def__init__(self, test):
        data={}
        if test>5:
            data["amount"] = test
            self.json_data = json.dumps(data)
        else:
            data["fail"] = test
            self.json_data = json.dumps(data)

    def to_json(self):
        return self.json_data

and call it with:

output = json.loads(ScanThis(8).to_json())

Now you can still use __str__ for another purpose. Furthermore by using to_json you make it explicit that the result will be a JSON string. Using str for JSON conversion is of course not forbidden, but str(..) as a name, does not provide much guarantees about the format of the result whereas to_json (or another similar name) strongly hints that you will obtain JSON data.

Upvotes: 7

Related Questions