Python Forum
How do I write class objects to a file in binary mode? - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: How do I write class objects to a file in binary mode? (/thread-21098.html)



How do I write class objects to a file in binary mode? - Exsul1 - Sep-13-2019

How do I write class instances to a file in binary mode? When I try to run this code,

from npc_gen import NPC

n1 = NPC()


a = open("workfile", "wb")

a.write(n1)

a.close()
I'm told:

Output:
Unexpected type(s): (NPC) Possible types: (bytearray) (bytes)
How do I convert a (custom) class object into a bytes object? Pickle?

Also, is this the best way to do what I want to do? I'm making my first app. Users will want to save some of the custom class objects that are created to their phones. I figured I'd need to have the program create a separate file to store those objects in. Is this best practice?

(Apologies if I have used any terms incorrectly or misunderstood something fundamental. I'm still new to programming, so please use easy-to-understand explanations in your answers. Thank you!)


RE: How do I write class objects to a file in binary mode? - micseydel - Sep-13-2019

I recommend against pickle for reasons that are easy to Google. If it were me, I'd probably just add a method to my class called toJson and have a function to produce the class from that JSON. You may also consider jsonpickle.


RE: How do I write class objects to a file in binary mode? - Exsul1 - Sep-14-2019

This seems unnecessarily complicated for something seemingly as simple as storing data. How do people usually do it?


RE: How do I write class objects to a file in binary mode? - ndc85430 - Sep-14-2019

It's difficult to suggest an appropriate solution when you've given very little context. What is the application for? What kind of data does it need to store and what does it need to do with that data?

Common solutions include databases when you need to query (or update) for data in different ways, or some kind of file storage (S3, Google Buckets, etc.) when you just need to store files for retrieval later. Again, it's not clear what your needs are so help us by filling in the blanks.


RE: How do I write class objects to a file in binary mode? - Exsul1 - Sep-14-2019

(Sep-14-2019, 03:11 AM)ndc85430 Wrote: It's difficult to suggest an appropriate solution when you've given very little context. What is the application for? What kind of data does it need to store and what does it need to do with that data?

Common solutions include databases when you need to query (or update) for data in different ways, or some kind of file storage (S3, Google Buckets, etc.) when you just need to store files for retrieval later. Again, it's not clear what your needs are so help us by filling in the blanks.


I'm creating an Android app with Kivy that uses the random module to generate unique NPCs for DMs of D&D and other tabletop roleplaying games. I created the class, NPC. With the push of a button, users can generate NPC class objects with random characteristics (within the limitations of rules I've created to make them sound realistic). If they find an interesting NPC, they will want to save it to their phone for later use, modify it, or share it using the standard sharing options in Android. I've just finished the NPC creation stage, and now I've moved on to the task of creating a way to store these class objects.

I assumed that the best way to do that would be to have the program create a separate file containing the class objects the user wants to keep. In order to do that, I think I need to convert these custom class objects to bytes objects. If there is an easy or built-in way to do that, I'd love to hear it, as writing to a file in text mode would not, I think, successfully store a class object. It looks like I'd be using JSON or Pickle otherwise, which I'm fine with learning; I just want to make sure I'm not overly complicating things.


RE: How do I write class objects to a file in binary mode? - Exsul1 - Sep-14-2019

After talking with some folks in another forum, best practice might be not to store the class object at all, but rather to store the attributes of those objects to a list or dictionary and then recreate them later. But I didn't understand their explanation of how to do that. This was the example they gave me:

class Dog:
    def __init__(self, name, color, age):
        self.name = name
        self.color = color
        self.age = age

    def bark():
        print("Woof")

    def eat_homework(file):
        with open(file, "w") as homework:
            homework.write("")

doggo = Dog("Spot", "Black and White", 2)
#Instead of saving Dog object we can just save the attributes
#doggo.name, doggo.color, doggo.age --- that's all the info we need to
#recreate our object.
#in this case, all you'd have to write to a file is:
#["Spot", "Black and White", 2]
Lines 11-12 don't appear to be writing anything to file.


RE: How do I write class objects to a file in binary mode? - micseydel - Sep-14-2019

It appears they borked their example. From the comment, it looks like that was supposed to be a list, using your attributes, not an empty string. Besides that, neither method has a self argument, so the example would result in an error. And they don't even attempt to show reading, as opposed to writing. What forum did you go to? Generally, it's seen as polite to inform both forums of each other to prevent duplicate work.

As for your problem - I recommend not writing a straight list to a file. Create a dict/list (either is fine; I would probably prefer a dict because I think it's more human-readable, assuming file size / performance are not at issue), then use the json module to dump that Python object to disk as JSON. You can then use the same module to read that back from a file and then you can build your class from whatever you read from disk.


RE: How do I write class objects to a file in binary mode? - snippsat - Sep-14-2019

There are small database packages that is fine for this eg TinyDB or dataset.
I have tutorial about dataset here.

Can do test with TinyDB,will store and also do trick(**) to recreate class instantiating from DB.
>>> from tinydb import TinyDB, Query

>>> db = TinyDB('db.json')
>>> doggo = Dog("Spot", "Black and White", 2)
>>> fido = Dog("Fiff", "Brown", 4)

>>> db.insert(doggo.__dict__)
1
>>> db.insert(fido.__dict__)
2

>>> db.all()
[{'name': 'Spot', 'color': 'Black and White', 'age': 2}, {'name': 'Fiff', 'color': 'Brown', 'age': 4}]
>>> exit()
Now have date in db.json.
Load again.
>>> from tinydb import TinyDB, Query

>>> db = TinyDB('db.json')
>>> find = Query()
>>> doggo = db.search(find.name == 'Spot')[0]
>>> doggo
{'name': 'Spot', 'color': 'Black and White', 'age': 2}

# Now the trick,using data from DB to recreate the class
>>> doggo = Dog(**doggo)

>>> doggo.name
'Spot'
>>> doggo.color
'Black and White'