Home > Net >  How to read parameters from a file when inside a class?
How to read parameters from a file when inside a class?

Time:12-23

Suppose I have a Python class like this:

class Person:
  def __init__(self): 
    self.alive = True
    self.name = 'Alice'
    self.age = 20

How can I read parameters from an external file inside this class? I imagine it could be something like the following pseudocode:

class Person:
  def __init__(self, filename): 
    self.alive = True                    # same for all persons
    with open(filename, 'r') as f: 
      self.name = f.somehow_read_name    # different for all persons
      self.age = f.somehow_read_age

such that I can do:

alice = Person('alice.txt')
bob = Person('bob.txt')

I'd like the external 'alice.txt' file to be human-readable, so maybe something like this:

name = 'Alice' # Name of the person
age  = 20      # Age of the person
### OR ###
{
name : 'Alice', # Name of the person
age  : 20       # Age of the person
}
### OR ###
self.name = 'Alice'
self.age  = 20

where the order of the parameters is not important. Until now, I've been doing this:

with open(filename, "r") as f:
  parameters = f.readlines()
  self.name = parameters[8]

This is obviously very tedious to maintain when something changes inside the 'alice.txt' file.

CodePudding user response:

This solution creates a parser for the human-readable file

Code

class Person:
    def __init__(self, filenm): 
        self.alive = True
        # Get attributes as dictionary
        d = get_attributes_from_file(filenm)

        # Set attributes from dictionary
        for k, v in d.items():
            setattr(self, k, v)

    def __str__(self):
        # Atributes of object as string (to allow printing of object)
        return str(self.__dict__)
        
def get_attributes_from_file(filenm):
    '''
        Parses attribute file
            returns dictionary of attributes
    '''
    
    
    with open(filenm, 'r') as f:
        # Read file contents
        s = f.read()

        # remove comments
        s = ' '.join(x.split('#')[0] for x in s.splitlines())   
        
        # Convert to dictionary
        # uses comma as delimiter
        d = dict([
                    (term.split(':')[0].strip(), term.split(':')[1].strip("' "))
                    for term in s.strip("{}").split(',')
                ])
    
    return d

Usage

tom = Person('tom.txt')
dick = Person('dick.txt')
mary = Person('mary.txt')
phyllis = Person('phyllis.txt')

print(tom)  # output: {'alive': True, 'name': 'tom', 'age': '20'}
print(dick) # outptu: {'alive': True, 'name': 'dick', 'age': '25'}
print(mary) # {'alive': True, 'name': 'mary', 'age': '35', 'gender': 'female'}
print(phyllis) # Output: {'alive': True, 'name': 'phyllis', 'age': '35', 'gender': 'female', 'sibling': 'tom'}

Files

tom.txt:

name: tom,            # comment such as this are ignored
age: 20               # age

dick.txt

name: dick,
age: 25

mary.txt

name: 'mary',       # attributes can be with or without quotes
age: 35,
gender: female     # can have extra attributes

phyllis.txt (shows comment only line and blank line)

name: 'phyllis',
age: 35,   # age in years

gender: female,
#relatives 
sibling: 'tom'

CodePudding user response:

Well you have two ways:

First, using pickle to store your python data in it and retrieve. Use this link for more info https://docs.python.org/3/library/pickle.html .

Second you can use specific file format to store and retrieve your data such as CSV, JSON , excel and etc... .

CodePudding user response:

I think I found a nice way. I tried to do from alice import * inside the class, which did not work (because of the *). However, as long as the external file is called ***.py and I import it inside the class like this:

import alice # if the file is 'alice.py'

then I can access the variables defined in that file via alice.name, etc. and do the following:

import alice
self.name = alice.name
self.age  = alce.age
  • Related