6
votes

Sous-classe d'importation d'une classe de base en python

J'ai une classe de base qui a une méthode qui crée une instance d'une sous-classe qui s'appelle la même chose que la chaîne d'entrée.

Ceci a fonctionné avant de mettre les sous-classes et la classe de base dans le même fichier et Quelque chose comme globals () [nom] .

Maintenant, cependant, j'ai divisé les sous-classes en d'autres fichiers. Ils ont chacun une instruction d'importation en haut, donc je ne peux donc pas simplement importer les sous-classes de ma classe de base ou une chaîne d'importation circulaire.

Y a-t-il une solution de contournement pour cela?

dans base.py : xxx

dans basefactory.py : xxx

dans file1.py : xxx


3 commentaires

Est-ce que résolve () juste pour déterminer le type de classe et renvoyer une nouvelle instance d'elle-même?


Il renvoie une instance d'une sous-classe de base.


Qu'en est-il de déménager à résoudre dans la classe d'usine, qui est responsable du retour du bon exemple?


3 Réponses :


6
votes

Vous pouvez déplacer l'instruction importer qui échoue à la méthode qui crée l'objet de sous-classe.


6 commentaires

Bien que cela fonctionne, quel est l'impact de la performance de cela? N'importerait pas 60 sous-classes chaque fois que la méthode est appelée (elle est faite de manière récursive) coûte cher?


Les modules importés sont mis en cache dans sys.modules , donc je ne m'attendrais pas à un impact significatif.


De plus, je dois faire quelque chose dans le sens de à partir de package.filename importer * pour chaque fichier. À l'avenir, je devrais m'empêcher d'ajouter plus d'importations à chaque fois que j'ajoute un nouveau fichier. Existe-t-il une syntaxe plus compacte pour importer tous les membres de tous les modules d'un package?


Vous pouvez faire un "package d'importation", puis des objets de référence comme package.filename.member1, package.filename2.member2, etc.


Étant donné que mon créateur d'instance de sous-classe est automatique (basé sur des chaînes), je ne sais pas dans quel fichier la sous-classe est dans.


Si vous ne connaissez pas dans quel module la mise en œuvre de la sous-classe sera à l'avance, vous devrez alors mettre en œuvre une sorte de mécanisme de découverte. Dans tous les cas, si je comprends bien, car vos cours ne seront pas fournis par des bibliothèques tierces, il pourrait suffire à les ajouter à __ tout __ dans l'emballage __ init __. Py < / Code> et importation à l'aide de à partir de l'importation de package * (cela nécessite une maintenance, cependant).



0
votes

Je ne sais pas si je te comprends, Pourquoi prenez-vous les sous-classes de la classe si vous en avez besoin d'eux? Laissez ensuite à l'intérieur de la classe et, partout où vous en avez besoin, vous pouvez à partir de la sous-classe d'importation de classe


2 commentaires

J'ai plus de 60 sous-classes. Auparavant, quand ils étaient dans le même fichier que ma classe de base, le fichier était supérieur à 800 loc. C'était plus ou moins impossible de trouver des choses.


60 sous-classes !! À quoi servent-ils?



6
votes

De ce que je comprends, vous avez:

  1. une classe de base li>
  2. une série de classes dérivées de la classe de base li>
  3. une méthode d'usine dans la classe de base qui instancie le type de classe dérivée correcte li>
  4. Les classes dérivées ont été divisées en fichiers et dépendent de la classe de base, mais la méthode d'usine de la classe de base dépend des classes dérivées li> ol>

    Une solution serait de créer une fonction / classe distincte pour la méthode d'usine et la mettre dans un fichier séparé de la classe de base. Ce fichier pourrait importer tous les fichiers de la classe de base et des classes dérivées sans la référence circulaire. P>

    par exemple: p> xxx pré>

    réellement, une meilleure méthode pourrait Soyez d'utiliser Type : P>

    Type (Nom, bases, dict) code> renvoie un nouvel objet de type. C'est essentiellement une forme dynamique de la déclaration de classe. La chaîne de noms est le nom de la classe et devient le nom __ __ code> attribut; Les bases TUPLE affichent les classes de base et devient la __ bases __ code>; et le dictionnaire dict code> est l'espace de noms contenant des définitions de classe de classe et devient l'attribut __ dict __ code>. Par exemple, les deux états suivants créent des objets de type identiques: P>

    >>> class X(object):
    ...     a = 1
    ...
    >>> X = type('X', (object,), dict(a=1))
    


7 commentaires

Cela propage simplement l'erreur d'importation à la classe d'usine. Depuis la classe d'usine, il suffit de à partir de sub1 importation * , à partir de sous -2 importe * ... et chaque sous-classe fait à partir de la base importe * , ceci jettera un importerror après avoir tenté d'importer des sous -2. Essayer d'attraper l'exception et de passer cela signifie que toutes les autres importations seront ignorées.


Sauf si vous mettez la classe d'usine dans son propre fichier.


Une autre solution peut être de maintenir un meilleur contrôle de vos sous-classes et de créer un dict qui spécifie le mappage entre la chaîne et votre classe dérivée et importer chacune de vos 60 classes de base dans la classe d'usine explicitement.


Je l'ai fait - ma classe d'usine importe tout de chaque sous-classe (qui importe la classe de base). Pendant ce temps, ma classe de base, qui se trouve dans un fichier séparé, importe la classe d'usine. Cela entraîne toujours une importation circulaire.


La classe de base n'a pas besoin de savoir sur la classe d'usine. Peut-être que vous pourriez poster du code sur la manière dont ils sont liés?


Cette question avait des conseils intéressants sur les usines de classe: Stackoverflow.com/questions/ 456672 / Classe-Factory-in-Python


La méthode que vous avez donnée ne fonctionne pas pour l'exemple de code que j'ai posté, car la classe de base appelle dans la classe d'usine.