Python Forum
How do I write class objects to a file in binary mode?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do I write class objects to a file in binary mode?
#1
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!)
Reply
#2
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.
Reply
#3
This seems unnecessarily complicated for something seemingly as simple as storing data. How do people usually do it?
Reply
#4
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.
Reply
#5
(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.
Reply
#6
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.
Reply
#7
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.
Reply
#8
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'
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Last record in file doesn't write to newline gonksoup 3 364 Jan-22-2024, 12:56 PM
Last Post: deanhystad
  How Write Part of a Binary Array? Assembler 1 305 Jan-14-2024, 11:35 PM
Last Post: Gribouillis
  write to csv file problem jacksfrustration 11 1,370 Nov-09-2023, 01:56 PM
Last Post: deanhystad
  python Read each xlsx file and write it into csv with pipe delimiter mg24 4 1,308 Nov-09-2023, 10:56 AM
Last Post: mg24
  How can I access objects or widgets from one class in another class? Konstantin23 3 929 Aug-05-2023, 08:13 PM
Last Post: Konstantin23
  How do I read and write a binary file in Python? blackears 6 6,010 Jun-06-2023, 06:37 PM
Last Post: rajeshgk
  Reading data from excel file –> process it >>then write to another excel output file Jennifer_Jone 0 1,046 Mar-14-2023, 07:59 PM
Last Post: Jennifer_Jone
  Read text file, modify it then write back Pavel_47 5 1,499 Feb-18-2023, 02:49 PM
Last Post: deanhystad
  how to read txt file, and write into excel with multiply sheet jacklee26 14 9,513 Jan-21-2023, 06:57 AM
Last Post: jacklee26
  How to write in text file - indented block Joni_Engr 4 6,362 Jul-18-2022, 09:09 AM
Last Post: Hathemand

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020