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