Python Forum
saving (in text or binary) an object under a defined class
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
saving (in text or binary) an object under a defined class
#1
Hi, I don't know if my topic makes any sense but what I'm trying to say is, I'm made a class
class Users:
    def __init__(self, fname, lname, bday, username, password, domain='gmail'):
        self.fn = fname
        self.ln = lname
        self.bd = bday
        self.un = username
        self.pw = password
        self.dom = domain

    def fullname(self):
        return(self.fn + ' ' + self.ln)

    def email(self):
        return(self.fn.lower() + '_' + self.ln.lower() + '@' + self.dom + '.com')

    def show_info(self):
        return(
            f''' The following is the info for user {self.un}:
    First Name: {self.fn}
    Last Name: {self.ln}
    Birthdate: {self.bd}
    Email: {self.fn}_{self.ln}@{self.dom}.com
            ''')
and I created an object under that class
user_1 = Users('Adam', 'Smith', '1/1/2000', 'adam1100', 1234)
As you see, my class is like a personal info sheet. My question is, how can I save this particular object to an external file (like a text or a binary file) which could be loaded as is (remain as a "User" class) the next time I ran the code. Like the external file should become a database or something.

I tried doing this
def save_info(self):
        x = f"'{self.fn}', '{self.ln}', '{self.bd}', '{self.un}', '{self.pw}', '{self.dom}'"
        with open('users', 'r+') as data:
            data.write(x)
which is a function under the class I made, yes it does save in a file however, whenever I'm reading the file using this
@staticmethod
    def load_info():
        with open('users', 'r+') as data:
             return(data.read())
and running this outside the code block of the class
z = Users.load_info()
user_1 = Users(z)
its returning an error
Error:
Traceback (most recent call last): File "c:\Users\***\Desktop\Python\Test\test.py", line 39, in <module> user_1 = Users(z) TypeError: __init__() missing 4 required positional arguments: 'lname', 'bday', 'username', and 'password'
I think what the interpreter is telling is that it can't recognize the output from the text file as a valid __init__ of the class (since it is telling me that the code does not have any positional arguments)

I tried printing the variable z and it shows what I'm expecting
Output:
'Adam', 'Smith', '1/1/2000', 'adam1100', '1234', 'gmail'
Can you please enlighten me. I'm confused with creating classed that's why I'm focusing on it. Thanks.

P.S.
If my question is kinda noob I'm so sorry since I'm really a beginner with programming in general so please bear with me. Thank you.
Reply
#2
one way is pickle module from Python Standard Library

here is tutorial on using pickle on Python Module of the week site


Another option is store instance attributes (if possible) as json file (or some other type of text file). In which case you need to create interface to reconstruct the object from that file.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#3
+1 to JSON. It's more work, but pickle is discouraged for security reasons so I make a habit of avoiding it.
Reply
#4
A look how to use this with TinyDb.
Can also mention dataset my tutorial,both of this make it easier to work with small databases.

First i gone fix the class a little,to make it more usable for use with TinyDb
This mean that can take data from TinyDB and use the class.
Will also have the power of TinyDB to eg Query(search).
See that i use self.fname = fname no shortcut,this will make it easier to insert data(Users(**user_1)) from TinyDb to use class.
class Users:
    def __init__(
        self, obj_name, fname, lname, bday, username, password, domain="gmail"):
        self.obj_name = obj_name
        self.fname = fname
        self.lname = lname
        self.bday = bday
        self.username = username
        self.password = password
        self.domain = domain

    @property
    def fullname(self):
        return f"{self.fname}  {self.lname}"

    @property
    def email(self):
        return f"{self.fname.lower()}_{self.lname.lower()}@{self.domain}.com"

    def __str__(self):
        return f"""\
            The following is the info for user {self.username}:
            First Name: {self.fname}
            Last Name: {self.lname}
            Birthdate: {self.bday}
            Email: {self.fname}_{self.lname}@{self.domain}.com
        """

    def __repr__(self):
        return (f'Users({self.obj_name}, {self.fname}, {self.lname}, '+
                f'{self.bday}, {self.username}, {self.password}, {self.domain})')

# --| Test users
# user_1 = Users('user_1', 'Adam', 'Smith', '1/1/2000', 'adam1100', 1234)
# user_2 = Users('user_2', 'Kent', 'Hollow', '5/5/1970', 'kent1200', 4567)
A quick example of __str__ and __repr__ that i put in.
λ ptpython -i db_test.py
>>> user_1 = Users('user_1', 'Adam', 'Smith', '1/1/2000', 'adam1100', 1234)

>>> # Use of __repr__
>>> user_1
Users(user_1, Adam, Smith, 1/1/2000, adam1100, 1234, gmail)

>>> # Use of __str__
>>> print(user_1)
            The following is the info for user adam1100:
            First Name: Adam
            Last Name: Smith
            Birthdate: 1/1/2000
            Email: [email protected]
Use TinyDb,see that i pass in a dictionary with use of __dict__.
λ ptpython -i db_test.py
>>> from tinydb import TinyDB, Query

>>> db = TinyDB('db.json')
>>> user_1 = Users('user_1', 'Adam', 'Smith', '1/1/2000', 'adam1100', 1234)
>>> user_2 = Users('user_2', 'Kent', 'Hollow', '5/5/1970', 'kent1200', 4567)

>>> db.insert(user_1.__dict__)
1
>>> db.insert(user_2.__dict__)
2
>>> exit()
Now i want to use data from database to use the class and also have the option to use TinyDb directly.
λ ptpython -i db_test.py
>>> from tinydb import TinyDB, Query

>>> db = TinyDB('db.json')
>>> User = Query()

# Now take data from DB and instantiate user_1 
>>> user_1 = db.search(User.obj_name == 'user_1')[0]
>>> user_1 = Users(**user_1)

>>> user_1
Users(user_1, Adam, Smith, 1/1/2000, adam1100, 1234, gmail)

# Now is class workings with data from DB.
>>> user_1.email
'[email protected]'

>>> user_1.fullname
'Adam  Smith'
TinyDb directly:
>>> db.search(User.lname == 'Hollow')
[{'obj_name': 'user_2', 'fname': 'Kent', 'lname': 'Hollow', 'bday': '5/5/1970', 'username': 'kent1200', 'password': 4567, 'domain': 'gmail'}]


>>> db.all()
[{'obj_name': 'user_1', 'fname': 'Adam', 'lname': 'Smith', 'bday': '1/1/2000', 'username': 'adam1100', 'password': 1234, 'domain': 'gmail'}, {'obj_name': 'user_2', 'fname': 'Kent', 'lname': 'Hollow', 'bday': '5/5/1970', 'username': 'kent1200', 'password': 4567, 'domain': 'gmail'}]


>>> db.all()[1]
{'obj_name': 'user_2', 'fname': 'Kent', 'lname': 'Hollow', 'bday': '5/5/1970', 'username': 'kent1200', 'password': 4567, 'domain': 'gmail'}
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  error in class: TypeError: 'str' object is not callable akbarza 2 418 Dec-30-2023, 04:35 PM
Last Post: deanhystad
  "Name is not defined" when running a class lil_e 6 3,675 Jan-12-2023, 11:57 PM
Last Post: lil_e
  Saving the print result in a text file Calli 8 1,679 Sep-25-2022, 06:38 PM
Last Post: snippsat
  python update binary object (override delivered Object properties) pierre38 4 1,687 May-19-2022, 07:52 AM
Last Post: pierre38
  saving and loading text from the clipboard with python program MaartenRo 2 1,602 Jan-22-2022, 05:04 AM
Last Post: MaartenRo
  Why built in functions are defined as class? quazirfan 5 2,686 Oct-23-2021, 01:20 PM
Last Post: Gribouillis
Exclamation win32com: How to pass a reference object into a COM server class Alfalfa 3 4,768 Jul-26-2021, 06:25 PM
Last Post: Alfalfa
  How to convert binary data into text? ZYSIA 3 2,556 Jul-16-2021, 04:18 PM
Last Post: deanhystad
  Extracting the text between each "i class" knight2000 4 2,264 May-26-2021, 09:55 AM
Last Post: knight2000
  Error when refering to class defined in 'main' in an imported module HeRo 2 2,308 Apr-13-2021, 07:22 PM
Last Post: HeRo

Forum Jump:

User Panel Messages

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