Bonjour à tous,

Je poursuis mon apprentissage de Python et de la programmation objet et plus ça va plus je trouve cela extrêmement intéressant et puissant.

Par contre il semble que je ne maitrise pas bien les espaces de noms !

Voila mon problème :

Mon application est un ensemble de traitements de calculs statistiques, qui utilisent des objets communs.

Pour cela j'ai donc créé :
un module S3Library.py qui contient mes objets communs fonctionnels
un module S3Tools.py qui contient des fonctions et des objets utilitaires

Dans S3Tools, j'ai créé une classe S3Log, dont le but est d'ouvrir (__init__) un fichier texte en écriture, puis, au fur et à mesure du déroulement du calcul d'y ajouter des messages (méthode log) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
class S3Log:
    """fichier log de traitement"""
    def __init__(self,fichier):
        self.logFile = open(fichier,'w')
 
    def log(self, niveau, message):
        log = str(datetime.now()) + " " + str(niveau) + " " + str(message) + "\n"
        self.logFile.write(log)
Cela marche d'ailleurs bien, lorsque j'exécute le code ci-dessous, cela crée bien mon fichier Log.txt et écrit bien une première ligne dans celui-ci :

$ cat Log.txt
2010-05-13 11:49:24.128577 0 Debut de traitement
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Codage :
# -*- coding:Utf-8 -*- 
 
# imports
import os
import csv
 
from S3Library     import *
from S3Tools        import *
 
# Création d'une instance de fichier de log
 
logFile = S3Log('Log.txt')
logFile.log(0,"Debut de traitement")
ensuite, ça ce corse :

Pour chaque ligne lue dans le fichier EntrepotData.csv, je crée une instance de la classe Entrepot (module S3Library.py)

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
# lecture des données et calcul
Reader = csv.DictReader(open('EntrepotData.csv'), delimiter=';',quotechar='"')
nomenclature = Reader.next()
 
for row in Reader:
# instanciation d'un entrepot
    entrepot = Entrepot(nomenclature, row)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -*- coding:Utf-8 -*- 
#                                                                              #
# Bibliothèque standard du moteur de calcul                                    #
#                                                                              #
# Cette bibliothèque contient l'ensemble des objets nécessaires au calcul      #
#                                                                              #
#______________________________________________________________________________#
 
from UserDict   import UserDict
from datetime   import datetime
 
from S3Tools    import *
 
# Classe Entrepot
class Entrepot:
 
    def __init__(self, nomenclature, entrepot):
        for k, v in entrepot.items():
            w = typage(nomenclature, k, v)
            setattr(self, k, w)
La fonction typage me permet de créer des attributs de l'instance Entrepot du bon type (chaine, entier, date, float,...) à partir des données de mon fichier csv qui sont toutes des strings. Cela me permet notamment de contrôler que les données reçues sont correctes (enfin au bon format..)

Cette fonction devrait me renvoyer un message dans le fichier de log si un attribut ne correspond pas à son type :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
def typage(nomenclature, cle, valeur): 
    logAtt = None                                   
    try:
        typeValeur = nomenclature[cle]
    except:
        logAtt  = 1
        logMess = "Fonction typage : %s, donnée inexistante" % (cle)
    else:
        if typeValeur == "cr":
            return valeur
        elif typeValeur == "en":
            try:
                return int(valeur)
            except:
                logAtt  = 1
                logMess = "Fonction typage: %s n'est pas un nombre entier valide (%s)" % (cle, valeur)
        elif typeValeur == "dc":
            try:
                return float(valeur)
            except:
                logAtt  = 1
                logMess = "Fonction typage: %s n'est pas un nombre décimal valide (%s)" % (cle, valeur)
        elif typeValeur == "dt":
            try:
                return datetime.strptime(valeur, "%d/%m/%Y")
            except:
                logAtt  = 1
                logMess = "Fonction typage: %s n'est pas une date valide (%s)" % (cle, valeur)
        elif typeValeur == "cr/en":
            try:
                return int(valeur)
            except:
                return valeur
        elif typeValeur == "cr/dc":
            try:
                return float(valeur)
            except:
                return valeur 
        elif typeValeur == "cr/dt":
            try:
                return datetime.strptime(valeur, "%d/%m/%Y")
            except:
                return valeur
 
        if logAtt:
            logFile.log(logAtt, logMess)
Et là, j'ai systématiquement le message :

logFile.log(logAtt, logMess)
NameError: global name 'logFile' is not defined

Je me doute qu'il s'agit d'un problème d'espace de nom, mais je sèche sur la solution. J'ai essayé de définir logFile comme global dans ma fonction typage, mais ça ne marche pas.

Merci à l'avance de votre aide.