effet de bord avec "if __name__ == '__main__'" sur les (noms de) classes
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:
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:
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:
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:
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 !