una paquetes otro modulos lista libreria importar directorio desde crear como comando bibliotecas python module circular-dependency

paquetes - lista de modulos de python



Dependencia del módulo Python (5)

¿De verdad necesita hacer referencia a las clases en el tiempo de definición de clase? es decir.

class CRoom(object): person = CPerson("a person")

O (más probable), solo necesita usar CPerson en los métodos de su clase (y viceversa). p.ej:

class CRoom(object): def getPerson(self): return CPerson("someone")

Si es el segundo, no hay problema, ya que para cuando se llama al método en lugar de definirse, el módulo se importará. Su único problema es cómo referirse a él. Es probable que estés haciendo algo como:

from CRoom import CPerson # or even import *

Con los módulos de referencia circular, no puede hacer esto, ya que en el punto en que un módulo importa otro, el cuerpo de los módulos originales no habrá terminado de ejecutarse, por lo que el espacio de nombres estará incompleto. En su lugar, use referencias calificadas. es decir:

#croom.py import cperson class CRoom(object): def getPerson(self): return cperson.CPerson("someone")

Aquí, python no necesita buscar el atributo en el espacio de nombres hasta que realmente se llame al método, momento en el cual ambos módulos deberían haber completado su inicialización.

Ok, tengo dos módulos, cada uno contiene una clase, el problema es que sus clases se referencian entre sí.

Digamos, por ejemplo, que tenía un módulo de sala y un módulo de persona que contenía CRoom y CPerson.

La clase CRoom contiene información sobre la sala y una lista CPerson de cada uno en la sala.

La clase CPerson, sin embargo, a veces necesita usar la clase CRoom para la sala, por ejemplo para encontrar la puerta, o también para ver quién más está en la sala.

El problema es que los dos módulos se importan entre sí. Acabo de recibir un error de importación que se está importando en segundo lugar :(

En c ++ podría resolver esto al solo incluir los encabezados, y dado que en ambos casos las clases solo tienen punteros a la otra clase, una declaración directa sería suficiente para el encabezado, por ejemplo:

class CPerson;//forward declare class CRoom { std::set<CPerson*> People; ...

¿Hay alguna forma de hacer esto en Python, aparte de colocar ambas clases en el mismo módulo o algo así?

editar: ejemplo agregado de python que muestra un problema al usar las clases anteriores

error:

Rastreo (llamadas recientes más última):
Archivo "C: / Projects / python / test / main.py", línea 1, en
desde la sala de importación CRoom
Archivo "C: / Projects / python / test / room.py", línea 1, en
de la persona que importa CPerson
Archivo "C: / Projects / python / test / person.py", línea 1, en
desde la sala de importación CRoom
ImportError: no se puede importar el nombre CRoom
room.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)


@ S.Lott, si no importo nada en el módulo de la sala, en su lugar obtengo un error indefinido (lo importé en el módulo principal como lo mostraste)

Rastreo (llamadas recientes más última):
Archivo "C: / Projects / python / test / main.py", línea 6, en
Ben = Room.AddPerson (''Ben'', ''Blacker'', ''Hombre'')
Archivo "C: / Projects / python / test / room.py", línea 12, en AddPerson
Person = CPerson (FirstName, SecondName, Gender, Id)
NameError: el nombre global ''CPerson'' no está definido

Además, la razón por la que hay diferentes módulos es donde encontré el problema para comenzar con la clase contenedora (por ejemplo, la sala) ya es de varios cientos de líneas, así que quería los elementos en ella (por ejemplo, las personas) en un archivo separado.

EDITAR: main.py

from room import CRoom from person import CPerson Room = CRoom() Ben = Room.AddPerson(''Ben'', ''Blacker'', ''Male'') Tom = Room.AddPerson(''Tom'', ''Smith'', ''Male'') Ben.Leave()


Podrías alias el segundo.

importar CRoom

CPerson = CRoom.CPerson


Primero, nombrar tus argumentos con letras mayúsculas es confuso. Como Python no tiene una comprobación de tipo estática formal, utilizamos UpperCase para UpperCase a una clase y lowerCase para lowerCase a un argumento.

En segundo lugar, no nos molestamos con CRoom y CPerson. La mayúscula es suficiente para indicar que es una clase. La letra C no se usa. Room Person .

En tercer lugar, generalmente no ponemos cosas en el formato de una clase por archivo . Un archivo es un módulo de Python, y con mayor frecuencia importamos un módulo completo con todas las clases y funciones.

[Soy consciente de que esos son hábitos; no es necesario que los rompa hoy, pero dificultan la lectura].

Python no utiliza tipos definidos estáticamente como C ++. Cuando define una función de método, no define formalmente el tipo de datos de los argumentos para esa función. Simplemente enumera algunos nombres de variables. Con suerte, la clase del cliente proporcionará argumentos del tipo correcto.

En tiempo de ejecución, cuando realiza una solicitud de método, Python debe asegurarse de que el objeto tenga el método. NOTA. Python no verifica si el objeto es del tipo correcto, eso no importa. Solo verifica si tiene el método correcto.

El bucle entre la habitación. room.Room y person.Person es un problema. No necesita incluir uno al definir el otro.

Es más seguro importar todo el módulo.

Aquí está room.py

import person class Room( object ): def __init__( self ): self.nextId= 0 self.people= {} def addPerson(self, firstName, secondName, gender): id= self.NextId self.nextId += 1 thePerson = person.Person(firstName,secondName,gender,id) self.people[id] = thePerson return thePerson

Funciona bien siempre que la Persona se defina finalmente en el espacio de nombres donde se está ejecutando. La persona no tiene que ser conocida cuando define la clase.

La persona no tiene que ser conocida hasta el tiempo de ejecución cuando se evalúa la expresión Persona (...).

Aquí está person.py

import room class Person( object ): def something( self, x, y ): aRoom= room.Room( ) aRoom.addPerson( self.firstName, self.lastName, self.gender )

Tu main.py parece a esto

import room import person r = room.Room( ... ) r.addPerson( "some", "name", "M" ) print r


No es necesario importar CRoom

No utiliza CRoom en person.py , así que no lo importe. Debido a la vinculación dinámica, Python no necesita "ver todas las definiciones de clase en tiempo de compilación".

Si realmente usa CRoom en person.py , cambie from room import CRoom a la import room y use la import room de formulario calificada por room.CRoom . Ver Effbot''s Circular Imports para más detalles.

Nota: probablemente tengas un error en Self.NextId += 1 línea. Incrementa NextId de instancia, no NextId de clase. Para incrementar el contador de la clase use CRoom.NextId += 1 o Self.__class__.NextId += 1 .