2009-06-25 4 views
6

나는 서로를 참조하는 두 개의 클래스가 있지만 컴파일러가 불평하는 것은 분명합니다. 이 주위에 어떤 방법이 있습니까?서로를 참조하는 파이썬 클래스

EDIT 사실 내 코드는 행크 게이가 사용하는 것보다 약간 다릅니다. 그래서 파이썬은 어떤 종류의 순환 참조를 확실히 처리 할 수 ​​있지만 다음과 같은 상황에서 오류를 발생시킵니다. 아래에 제가 가진 것은 무엇이며 '이름 Y 정의 오류가 없습니다'라는 메시지가 나타납니다.

class X(models.Model): 

     creator = Registry() 
     creator.register(Y) 

class Y(models.Model): 
    a = models.ForeignKey(X) 
    b = models.CharField(max_length=200) 

이 정보가 도움이되기를 바랍니다. 어떤 제안.

+4

"확실한"것은 무엇입니까? 어디에서 불평합니까? 코드 보이시겠습니까? 파이썬에서 순환 참조는 문제가되지 않으며 문제는 다른 곳에서 발생합니다. –

+0

코드는 어떻게 생겼습니까? –

+0

와우 ... * 롤리 즈 * – Robbie

답변

15

파이썬에서 클래스의 코드는 클래스가로드 될 때 실행됩니다.

이제 대체 무슨 뜻입니까? 코드를 포함하는 모듈을로드 할 때

class x: 
    print "hello" 
    def __init__(self): print "hello again" 

, 파이썬은 hello를 인쇄합니다 ;-)

는 다음과 같은 코드를 생각해 보자. x을 만들 때마다 파이썬은 hello again을 인쇄합니다.

def __init__(self): ...__init__ = lambda self: ...과 동일하다고 생각할 수 있습니다. 단, python 람다 제한이 적용되지 않습니다. 즉, def은 할당이며, 메소드 외부의 코드가 실행되는 이유를 설명 할 수 있습니다.

코드를 모듈이로드 될 때 Y에 값이 전에, Y를 참조

class X(models.Model): 
    creator = Registry() 
    creator.register(Y) 

말한다. 당신은 과제로 class X 생각할 수있다 (하지만 오프 손 익명 클래스를 작성하기위한 구문을 기억할 수없는, 어쩌면 type의 호출이있어?)

가 무엇을 수행 할 수 있습니다 것은 이것이다 :

class X(models.Model): 
    pass 
class Y(models.Model): 
    foo = something_that_uses_(X) 
X.bar = something_which_uses(Y) 

Y이 작성된 후 Y을 참조하는 X의 클래스 속성을 작성하십시오. 또는 그 반대의 경우 : Y을 먼저 작성한 다음 X을 작성한 다음 X에 의존하는 Y의 속성을 작성하십시오.

희망이

2

업데이트 : 그는 내 대답 후에 질문을 변경했습니다. 현재 받아 들여진 해결책은 새로운 질문에 비추어 더 낫습니다.

무슨 말씀입니까?

class A(object): 
    def __init__(self): 
     super(A, self).__init__() 


    def b(self): 
     return B() 


class B(object): 
    def __init__(self): 
     super(B, self).__init__() 


    def a(self): 
     return A() 

이 코드는 정상적으로 컴파일되어 실행됩니다.

+0

몇 가지 추가 정보 : 예, 작동합니다. 그러나 그것은 가격으로 제공됩니다 : 모든 클래스를 하나의 파일에 넣는 경우에만 작동합니다. 이것은 매우 불편합니다. 그것은 매우 불쾌 할 수 있습니다. 잘 모르겠지만 각 공개 클래스에 대해 고유 한 파일을 사용하는 좋은 OOP 연습으로 깨집니다. –

2

메서드 내에서 작업하는 동안 클래스 개체에 액세스 할 수 있습니다.

creator.register(Y)__init__으로 옮기면 위의 예는 문제가 없습니다. 그러나 메소드 외부의 클래스에 대한 순환 참조는 가질 수 없습니다.

+1

이 대답은 아무 것도 설명하지 않습니다. Jonas와 John Machin의 답변에서 설명하는 실제 문제를 이해하거나 설명하지 않고 "해결 방법"을 제공합니다. –

2

오류가 creator.register(Y)의 실행은 클래스 X의 (실행) 정의 중 시도입니다 :) 데 도움이, 그리고 그 단계에서, 클래스 Y는 정의되어 있지 않습니다. 이해 : classdef은 (일반적으로 가져 오기 시간에) 실행되는 명령문입니다. 그들은 "선언"이 아닙니다.

제안 : 귀하가 달성하고자하는 것을 알려주십시오. 아마도 새로운 질문 일 수 있습니다.

-2

문제는 대부분 파이썬이 아닙니다. 나는 그것이 SQL 문제라고 생각할 것이다. 클래스는 추상화 레이어를 통해 SQL 쿼리로 변환되어 테이블을 만듭니다. 아직 존재하지 않는 테이블을 다른 테이블에서 참조하려고합니다.

나는, SQL에서는 참조하지 않고 먼저 테이블을 만들어이 문제를 해결 것이고, 그 후 이러한 참조를 만들기 위해이를 수정,

그러나 나는 내 대답은 확실하지 않다, 그래서 조미료를 많이 받아 Django의 데이터베이스 추상화 계층이 상호 참조를 멋지게 처리하지 않는다면 실제로 상당히 놀랄 것입니다.

관련 문제