Pour tester les modules que j'écris, il m'arrive souvent d'écrire un bout de code supplémentaire à des fins de test (le classique "if __name__ == '__main__' ... " qui a le bon goût de n'être exécuté que quand on appelle directement le module et non pas quand on l'importe)

Sauf que !

Si cette partie de code suit une déclaration/définition de classe, un test avec 'isinstance' sur un objet de la dite-classe dans un autre module ne fonctionne plus car la classe est alors reconnue comme '__main__.nom_de_la_classe' et non plus comme 'nom_du_module.nom_de_la_classe'

Exemple :

dans classe_1.py
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
import classe_2
 
class Classe_1(object):
 
    def __init__(self,nom):
        self.nom = nom
 
if __name__ == "__main__":
    obj1 = Classe_1('un')
    obj2 = classe_2.Classe_2('deux',obj1)
dans classe_2.py
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
import classe_1
 
class Classe_2(object):
 
    def __init__(self,nom,obj_classe_1):
 
        assert isinstance(obj_classe_1,classe_1.Classe_1), type(obj_classe_1)        
        self.nom           = nom
        self.lien_classe_1 = obj_classe_1
En interactif, tout se passe bien :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
~ $ python
Python 2.5.2 (r252:60911, Feb 22 2008, 07:57:53) 
[GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import classe_1
>>> import classe_2
>>> obj1 = classe_1.Classe_1('un')
>>> obj2 = classe_2.Classe_2('deux',obj1)
>>> type(obj1)
<class 'classe_1.Classe_1'>
Mais si j'exécute directement classe_1.py :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
 
~ $ python classe_1.py
Traceback (most recent call last):
  File "classe_1.py", line 10, in <module>
    obj2 = classe_2.Classe_2('objet_2',obj1)
  File "/Users/pascal/classe_2.py", line 6, in __init__
    assert isinstance(obj_classe_1,classe_1.Classe_1), type(obj_classe_1)        
AssertionError: <class '__main__.Classe_1'>
~ $
Ce n'est évidemment pas un bug mais au moins un cas un peu particulier qui fait qu'un code correct s'avère "défaillant" quand on le teste de cette façon !