문제

좋아, 각각 클래스가 포함 된 두 개의 모듈이 있습니다. 문제는 수업이 서로를 참조하는 것입니다.

예를 들어 룸 모듈과 Croom 및 Cperson이 포함 된 사람 모듈이 있다고 가정 해 봅시다.

Croom 클래스에는 방에 대한 정보와 방에있는 모든 사람의 CPERSON 목록이 포함되어 있습니다.

그러나 CPERSON 클래스는 때때로 문을 찾거나 다른 방에있는 사람을 확인하기 위해 방에 객실의 크룸 클래스를 사용해야합니다.

문제는 서로를 가져 오는 두 모듈이 두 번째로 가져 오는 수입 오류를 얻는 것입니다.

C ++에서는 헤더를 포함하여 이것을 해결할 수 있으며, 두 경우 모두 수업은 다른 클래스에 대한 포인터를 가지고 있기 때문에 앞으로 선언은 헤더에게 충분합니다.

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

어쨌든 두 클래스를 동일한 모듈에 배치하는 것 외에는 파이썬 에서이 작업을 수행해야합니까?

편집 : 위의 클래스를 사용하여 문제를 보여주는 Python 예제 추가

오류:

Traceback (가장 최근의 호출) :
"c : projects python test main.py", 1 행,
객실 수입 크룸에서
"c : projects python test room.py", 1 행,
사람에게서 cperson을 수입합니다
"c : projects python test person.py", 1 행,
객실 수입 크룸에서
Importerror : 이름 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)
도움이 되었습니까?

해결책

Croom을 가져올 필요가 없습니다

당신은 사용하지 않습니다 CRoom 안에 person.py, 그것을 가져 오지 마십시오. 동적 바인딩으로 인해 Python은 "컴파일 시간에 모든 클래스 정의를 볼 필요가 없습니다".

당신이 실제로 하다 사용 CRoom 안에 person.py, 그런 다음 변경됩니다 from room import CRoom 에게 import room 모듈 자격 양식을 사용하십시오 room.CRoom. 보다 Effbot의 원형 수입 자세한 내용은.

사이드 노트 : 당신은 아마도 오류가있을 것입니다 Self.NextId += 1 선. 그것은 증가합니다 NextId 예를 들어 NextId 수업의. 클래스의 카운터 사용을 증분합니다 CRoom.NextId += 1 또는 Self.__class__.NextId += 1.

다른 팁

실제로 클래스 정의 시간에 클래스를 참조해야합니까? 즉.

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

또는 가능성이 높습니다. 수업 방법에서 CPERSON을 사용하면됩니다 (그 반대). 예 :

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

두 번째는 문제가 없다면 - 메소드가 얻을 때와 마찬가지로 ~라고 불리는 정의되지 않고 모듈이 가져옵니다. 당신의 유일한 문제는 그것을 참조하는 방법입니다. 아마도 당신은 다음과 같은 일을하고있을 것입니다.

from CRoom import CPerson # or even import *

원형 참조 모듈을 사용하면 하나의 모듈이 다른 모듈을 가져 오는 것처럼 원래 모듈 본체가 실행되지 않았으므로 네임 스페이스가 불완전하게됩니다. 대신 자격을 갖춘 참조를 사용하십시오. 즉:

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

여기서, 파이썬은 메소드가 실제로 호출 될 때까지 네임 스페이스의 속성을 조회 할 필요가 없으며,이 시간까지 두 모듈 모두 초기화를 완료해야합니다.

첫째, 대문자로 당신의 주장을 지명하는 것은 혼란 스럽습니다. 파이썬은 공식적인 정적 유형 확인이 없으므로 우리는 다음을 사용합니다. UpperCase 수업을 의미합니다 lowerCase 인수를 의미합니다.

둘째, 우리는 Croom과 Cperson을 귀찮게하지 않습니다. 어퍼 케이스는 그것이 클래스임을 나타 내기에 충분합니다. 문자 C는 사용되지 않습니다. Room. Person.

셋째, 우리는 일반적으로 물건을 넣지 않습니다 파일 당 하나의 클래스 체재. 파일은 파이썬 모듈이며 모든 클래스와 기능으로 전체 모듈을 더 자주 가져옵니다.

나는 이것이 습관이라는 것을 알고 있습니다. 오늘은 습관을 깰 필요는 없지만 읽기가 어렵습니다.

Python은 C ++와 같은 정적으로 정의 된 유형을 사용하지 않습니다. 메소드 함수를 정의 할 때 해당 기능에 대한 인수의 데이터 유형을 공식적으로 정의하지 않습니다. 당신은 단지 변수 이름을 나열합니다. 바라건대, 클라이언트 클래스는 올바른 유형의 인수를 제공하기를 바랍니다.

실행 시간에 메소드 요청을 할 때 Python은 객체에 메소드가 있는지 확인해야합니다. 노트. 파이썬은 객체가 올바른 유형인지 확인하지 않습니다. 올바른 방법이 있는지 확인합니다.

사이의 루프 room.Room 그리고 person.Person 문제입니다. 다른 것을 정의 할 때 하나를 포함 할 필요가 없습니다.

전체 모듈을 가져 오는 것이 가장 안전합니다.

여기에 있습니다 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 

사람이 결국 실행중인 네임 스페이스에서 정의되는 한 잘 작동합니다. 수업을 정의 할 때 사람을 알 필요가 없습니다.

사람 (...) 표현이 평가 될 때 런타임까지 사람을 알 필요는 없습니다.

여기에 있습니다 person.py

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

당신의 main.py 이렇게 보인다

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

두 번째는 별칭을 할 수 있습니다.

import CRoom

CPerson = CRoom.CPerson

@s.lott 룸 모듈로 아무것도 가져 오지 않으면 정의되지 않은 오류가 나타납니다 (내가 보여준 것처럼 기본 모듈로 가져 왔습니다)

Traceback (가장 최근의 호출) :
"c : projects python test main.py", 6 행,
Ben = room.addperson ( 'Ben', 'Blacker', 'Male')
"C : Projects Python Test Room.py", 12 행, AddPerson에서 파일
person = cperson (FirstName, SecondName, Gender, ID)
nameerror : 글로벌 이름 'cperson'은 정의되지 않았습니다.

또한, 다른 모듈이있는 이유는 컨테이너 클래스 (IEG 객실)부터 시작하는 문제가 이미 수백 줄이므로 분리 된 파일의 항목 (예 : 사람들)을 원했습니다.

편집 : 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()
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top