1
I’m having trouble organizing my code.
Ex: I would like to put generic functions, as pro example those that deal with reading a configuration file in only one place (read that the __init__.py
is perfect for this). However, I cannot.
This is the current organization of my code:
├── nome_projeto
│ ├── nome_projeto.py
│ ├── config.ini
│ ├── database.py
│ └── __init__.py
├── README.md
├── requirements.txt
└── setup.py
This is the contents of my __init__.py
, which includes the log settings, the configuration file and also a function that returns a parameter from the configuration file.
"""Funções básicas usadas pelo programa"""
import os
import logging
import pathlib
import datetime
import configparser
# Arquivo de configuração
CONFIG_FILE = 'config.ini'
CONFIG_PATH = ''.join([str(pathlib.Path(__file__).parent), '/', CONFIG_FILE])
if os.path.exists(CONFIG_PATH):
config = configparser.ConfigParser()
config.read(CONFIG_PATH)
else:
logging.error(f'Conf file not found: {CONFIG_FILE}')
# Cria diretório temporário se não existir
try:
if not os.path.exists(config['DEFAULT']['TempDir']):
# Temp dir
os.makedirs(config['DEFAULT']['TempDir'])
if not os.path.exists(config['DEFAULT']['Log']):
# Verifica se existe, se não, cria
log_file = open(config['DEFAULT']['Log'])
log_file.write(f"Created at {str(datetime.datetime.today())}")
log_file.close()
elif not os.access(config['DEFAULT']['Log'], os.W_OK):
# Verifica se tem permissão de escrita
logging.error(f"No permision to write: {config['DEFAULT']['Log']}")
except Exception as e:
logging.error(f'Fail during creation: {e}')
# Log
log_format = '%(asctime)s [%(filename)s:%(lineno)d] %(message)s'
logging.basicConfig(filename=config['DEFAULT']['Log'],
format=log_format, level=logging.DEBUG)
def get_conf(param):
"""Retorna parametro"""
return config['CONF'][param]
And here is one of the files of my project that would use the function get_config
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Database access.
"""
import pymysql
import logging
from . import get_conf
from pymysql import Error
def connect():
"""Abre coneção"""
try:
connection = pymysql.connect(host=get_conf('Address'),
user=get_conf('DatabaseUser'),
password=get_conf('DatabasePassword'),
db=get_conf('Database'),
charset='utf8mb4')
except Error as e:
logging.error(e)
cursor = connection.cursor()
return connection, cursor
def close(connection):
"""Commita e fecha coneção"""
connection.commit()
connection.close()
def lookup(option, tell):
""" Recebe uma opção e o telefone.
Retorna ou a senha, ou a contrasenha baseado na opção.
"""
try:
connection, cursor = connect()
if option == 'pass':
col = 'password_col_name'
else:
col = 'counter_password_col_name'
cursor.execute(f"""
SELECT {col} FROM table_name WHERE col_phone_number = {tell};
""")
return cursor.fetchone()
except Error as e:
logging.error(e)
if __name__ == "__main__":
"""Caso seja executado sozinho"""
print(f"""
Database: \t\t{get_conf('Database')}
Address: \t\t{get_conf('Address')}
Database User: \t{get_conf('DatabaseUser')}
Database Password: \t{get_conf('DatabasePassword')}
""")
First I’d like to understand if what I’m trying to do is right. I should store this kind of thing inside the __init__.py
? And I would also like to try to understand why I’m not being able to use the function, since I care about the . and only get an error message Import: attempted relative import with no known Parent package?
Pathlib is about making life easier, not complicated - instead of
CONFIG_PATH = ''.join([str(pathlib.Path(__file__).parent), '/', CONFIG_FILE])
just putCONFIG_PATH = pathlib.Path(__file__).parent / CONFIG_FILE
- no need to transform into string, and then use string features to join the parts.– jsbueno
And there, the CONFIG_PATH, being an object
Path
, and not a string, already has the methodexists
straightforward:if CONFIG_PATH.exists():
- pathlib came to join several arqiuvo features that were scattered in the standard library - including "read" and "write".– jsbueno