Dépendance du module Python
Ok j'ai deux modules, chacun contenant une classe, le problème est de leur classe de référence les uns des autres.
Permet de dire que j'ai eu par exemple un module de la salle et une personne module contenant CRoom et CPerson.
La CRoom classe contient les informations sur la chambre, et un CPerson liste de tous dans la salle.
La CPerson classe mais parfois besoin d'utiliser le CRoom classe pour la salle de sa, par exemple pour trouver la porte, ou trop voir qui d'autre est dans la chambre.
Le problème est avec les deux modules de l'importation de chaque d'autres, j'ai juste une erreur d'importation sur qui est importé deuxième 🙁
En c++ j'ai pu le résoudre en seulement, y compris les en-têtes, et puisque dans les deux cas, les classes ont juste des pointeurs vers les autres de la classe, une déclaration suffit pour l'en-tête par exemple:
class CPerson;//forward declare
class CRoom
{
std::set<CPerson*> People;
...
Est-il de toute façon à le faire en python, autres que de placer les deux classes dans le même module ou quelque chose comme ça?
edit: ajout de l'exemple python montrant problème à l'aide de classes ci-dessus
erreur:
Traceback (most recent call last):
Fichier "C:\Projects\python\test\main.py", line 1, in
à partir de la salle d'importation CRoom
Fichier "C:\Projects\python\test\room.py", line 1, in
d'une personne à l'importation CPerson
Fichier "C:\Projects\python\test\person.py", line 1, in
à partir de la salle d'importation CRoom
ImportError: impossible d'importer le nom de CRoom
chambre.py
from person import CPerson
class CRoom:
def __init__(Self):
Self.People = {}
Self.NextId = 0
def AddPerson(Self, FirstName, SecondName, Gender):
Id = Self.NextId
Self.NextId += 1#
Person = CPerson(FirstName,SecondName,Gender,Id)
Self.People[Id] = Person
return Person
def FindDoorAndLeave(Self, PersonId):
del Self.People[PeopleId]
person.py
from room import CRoom
class CPerson:
def __init__(Self, Room, FirstName, SecondName, Gender, Id):
Self.Room = Room
Self.FirstName = FirstName
Self.SecondName = SecondName
Self.Gender = Gender
Self.Id = Id
def Leave(Self):
Self.Room.FindDoorAndLeave(Self.Id)
source d'informationauteur Fire Lancer
Vous devez vous connecter pour publier un commentaire.
Pas besoin d'importer CRoom
Vous n'utilisez pas
CRoom
dansperson.py
afin de ne pas l'importer. En raison de liaison dynamique, Python n'a pas besoin de "voir toutes les définitions de classe au moment de la compilation".Si vous avez réellement ne utilisation
CRoom
dansperson.py
puis changerfrom room import CRoom
àimport room
et l'utilisation du module qualifié formeroom.CRoom
. Voir Effbot Circulaire Importations pour plus de détails.Note: vous avez probablement une erreur dans
Self.NextId += 1
ligne. Il incrémenteNextId
d'exemple, ne pasNextId
de classe. Pour incrémenter la classe comptoirCRoom.NextId += 1
ouSelf.__class__.NextId += 1
.Avez-vous réellement besoin de faire référence à la les classes à la définition de la classe de temps? ie.
Ou (plus probablement), avez-vous juste besoin d'utiliser CPerson dans les méthodes de votre classe (et vice versa). par exemple:
Si le second, il n'y a pas de problème, comme par le temps, la méthode obtient appelé plutôt que d'être définis, le module est importé. Votre seul problème est de savoir comment vous y référer. Il est probable que vous êtes en train de faire quelque chose comme:
Avec la circulaire référencement de modules, vous ne pouvez pas faire cela, car au point un module d'importations de l'autre, les modules d'origine corps n'aurez pas fini de l'exécution, de sorte que l'espace de noms sera incomplète. Au lieu de cela, utiliser qualifié références. c'est à dire:
Ici, python n'a pas besoin pour la recherche de l'attribut dans l'espace de noms jusqu'à ce que la méthode est appelée, par laquelle les deux modules doivent avoir terminé leur initialisation.
Tout d'abord, de nommage de vos arguments avec des majuscules est source de confusion. Depuis le Python n'a pas formelle, vérifier le type statique, nous utilisons la
UpperCase
à dire une classe etlowerCase
pour signifier un argument.Deuxièmement, nous ne vous embêtez pas avec CRoom et CPerson. Les majuscules sont suffisantes pour indiquer que c'est une classe. La lettre C n'est pas utilisé.
Room
.Person
.Troisième, nous n'avons pas l'habitude de mettre les choses en Une Classe Par Fichier format. Un fichier est un module Python, et nous avons le plus souvent de l'import d'un module complet avec toutes les classes et fonctions.
[Je suis conscient que ce sont des habitudes -- vous n'avez pas besoin de casser aujourd'hui, mais ils ne le font qu'il est difficile à lire.]
Python n'utilise pas définis de manière statique des types comme C++. Lorsque vous définissez une méthode de fonction, vous n'avez pas officiellement définir le type de données des arguments de la fonction. Il vous suffira simplement d'une liste de certains des noms de variables. Heureusement, la classe client fournira des arguments du type correct.
Au moment de l'exécution, lorsque vous faites une demande de méthode, puis Python doit être sûr que l'objet a de la méthode. REMARQUE. Python ne vérifie pas si l'objet est le type de droit -- qui n'a pas d'importance. Il vérifie seulement pour voir si elle a la bonne méthode.
La boucle entre
room.Room
etperson.Person
est un problème. Vous n'avez pas besoin d'inclure lors de la définition de l'autre.Il est plus sûr d'importer l'ensemble du module.
Voici
room.py
Fonctionne bien aussi longtemps que la Personne est finalement définie dans l'espace de noms où cela est en cours d'exécution. Personne n'a pas à être connues lorsque vous définissez la classe.
Personne n'a pas à être connu jusqu'à l'exécution lorsque la Personne(...) l'expression est évaluée.
Voici
person.py
Votre
main.py
ressemble à ceciVous pouvez simplement alias le second.
@S. Lott
si je ne suis pas d'importer quoi que ce soit dans le module de la salle, j'obtiens une erreur undefined à la place (je l'ai importé dans le module principal, comme vous l'a montré)
Aussi, la raison pour laquelle il diffrent des modules est là que j'ai rencontré le problème pour démarrer avec la classe de conteneur (ieg de la chambre) est d'ores et déjà plusieurs centaines de lignes, donc je voulais les éléments qu'il contient (par exemple les personnes) dans un autre fichier.
EDIT:
main.py