2010-07-26 5 views
2

현재 PyGame을 사용하여 다중 파일 파이썬 (2.6.5) 게임을 작성하려고합니다. 문제는 "pyconsole.py"파일 중 하나가 기본 파일 "main.py"에 의해 가져온 다른 객체의 인스턴스에서 메소드를 호출 할 수 있어야한다는 것입니다. 문제는 모든 게임 개체 (플레이어의 배, 적의 배, 방송국 등)의 인스턴스를 보유 할 기본 파일의 목록을 가지고 있지만 그 안에있는 목록에서 메서드를 호출 할 수없는 것처럼 보입니다. 메인 루프가 시작되기 전에 "main.py"에서 from pyconsole import *을 수행하고 있음에도 불구하고 "pyconsole.py". 이것은 단순히 가능하지 않으며, 대신 M4를 사용하여 모든 파일을 하나의 단일 파일로 결합한 다음 바이트 코드 컴파일 및 테스트/배포해야합니까?파이썬 액세스 부모 객체 인스턴스

예 :

파이썬 이름, 클래스, 모든 물건의 내 다소 제한 이해 여기에 올바른 경우
bash$ cat test.py 
#!/usr/bin/python 

import math, distancefrom00 
foo = 5 

class BarClass: 
    def __init__(self): 
     self.baz = 10 
    def get(self): 
     print "The BAZ is ", self.baz 
    def switch(self) 
     self.baz = 15 
     self.get() 

bar = BarClass() 

def main(): 
    bar.switch() 
    print distancefrom00.calculate([2, 4]) 

if __name__ == '__main__': main() 

bash$ cat distancefrom00.py 
#!/usr/bin/python 

import math 
import test 

def calculate(otherpoint): 
    return str(math.hypot(otherpoint[0], otherpoint[1]))+" (foo = "+str(test.foo)+"; "+test.bar.get()+")" 

bash$ python test.py 
The BAZ is 15 
The BAZ is 10 
Traceback (most recent call last): 
    File "test.py", line 24, in <module> 
    if __name__ == '__main__': main() 
    File "test.py", line 22, in main 
    print distancefrom00.calculate([2, 4]) 
    File "/home/archie/Development/Python/Import Test/distancefrom00.py", line 8, in calculate 
    return str(math.hypot(otherpoint[0], otherpoint[1]))+" (foo = "+str(test.foo)+"; "+test.bar.get()+")" 
TypeError: cannot concatenate 'str' and 'NoneType' objects 

의 NoneType 이름 test.bar.get() 것을 의미한다 - 따라서는, test.bar - 아무것도에 할당되지 않은 .

+1

"방법을 호출 할 수없는 것 같습니다"라는 의미는 무엇입니까? 몇 가지 샘플 코드를 포함하고 예외를 제공하십시오. – viraptor

+0

아 - 그리고를 위해서. 자신의 안전을 위해 빌드 스크립트에 M4를 포함시키지 마십시오. 파이썬 모듈이 올바르게 작동하면 어딘가에 버그가 있습니다. M4는 악합니다. – viraptor

+0

호기심에서 벗어나 M4 ('-P' 플래그 사용을 잊어 버려서 기존 텍스트를 망가 뜨리지 않는다)는 어떨까요? – mmirate

답변

2

문제는 파일 중 하나 "pyconsole.py는"기본 파일 "main.py"수입 다른 객체의 인스턴스에 메서드를 호출 할 수 있어야한다는 것입니다.

이것은 단지 종속성이 잘못된 것처럼 들립니다. 일반적으로 메인 파일까지 '거꾸로'호출해서는 안됩니다. main.py는 다른 모든 것들을 함께 묶는 접착제 여야하며, 아무것도 의존해서는 안됩니다. 기술적으로 종속성은 directed acyclic graph이어야합니다. 의존성 그래프에서 한 사이클을 찾으면 일반 파일을 새 파일로 옮겨주기를 중단하십시오.

그래서 'pyconsole.py'에서 사용하는 'main.py'파일을 새 파일로 이동하십시오. 그런 다음 'main.py'및 'pyconsole.py'에서 새 파일을 가져옵니다.

+0

OK, 올바르게 이해한다면 리소스 (사운드/스프라이트 객체, 게임 객체 목록 등)의 모든 인스턴스를 별도의 파일에 저장하고 'main'으로 가져와야 함을 의미합니다. py',''pyconsole.py', 그리고 그 객체들을 처리하는 모든 것들을 포함하고 있습니까? 내 질문은 여기에 있습니다 : 실제로 그렇게 할 각 개별 파일을 "가져 오기"되는 각 파일의 네임 스페이스의 동일한 "복사본"에서 작업 할 수 또는 결국 각 네임 스페이스의 끝없는 복사본을 만드는 결국 것입니다 하나는 다른 하나의 파일에 의해 영향을 받는다 (이것은 분명히 선택의 행동이 아니다)? – mmirate

+1

이것은 실제로 자원의 인스턴스가 아니라 코드 종속성에 관한 것입니다. 원하는 곳마다 리소스를 인스턴스화 할 수 있습니다. 그러나 하나의 파일에 존재하며 다른 많은 파일에서 사용되는 객체를 가지고 있다면 전역 변수처럼 들리며 거의 항상 나쁜 생각입니다. 네임 스페이스 질문에 관해서는 한 프로그램 내에서 각 모듈 (즉, 가져온 파일)은 한 번만 존재합니다. 두 개의 다른 파일이 pyconsole에 액세스하는 경우 그 이름은 두 경우 모두 동일한 객체를 참조합니다. – Kylotan

+0

아, 그게 내가 이해하지 못했던거야. 나는 Python이 내부적으로 C# ++ 헤더 파일을'#include '에서 상수를 두 번 이상 사용하지 않도록 보호하는 것과 비슷한 스키마를 내부적으로 사용했는지 여부를 확신하지 못했습니다. 그걸 정리 해줘서 고마워. – mmirate

0

pyconsole의 개체를 main.py에 인스턴스화하고 있습니까? PyConsole이라는 클래스가 pyconsole에있는 경우 해당 __init__ 메서드에 게임 개체 목록을 가져 오는 매개 변수를 지정합니다. 그런 식으로 pyConsole 개체는 개체에 대한 참조를 갖게됩니다.

희망이 도움이됩니다. 파이썬이 가져온 모듈과 함께 작동하는 방식을 오해 한 것처럼 보입니다.

0

제출 된 코드의 문제점은 get 메서드의 BarClass 클래스가 메서드 본문에 print 문만 포함되어 있기 때문에 None 값을 반환한다는 것입니다. 따라서, distancefrom00.py에서 함수 calculate의 결과는 다음과 같습니다 당신은 get에 대한 호출에서 문자열을 반환하여이 문제를 해결할 수 TypeError: cannot concatenate a 'str' and 'NoneType' objects

따라서

str + str + str + str + None + str 

. 예 :

def get(self): 
    return "The BAZ is %s" % self.baz 

또한 두 파일에 순환 가져 오기가 있습니다. test.py 수입품은 distancefrom00.py이고, distancefrom00.py 수입품은 test.py입니다.Kylotan에 따르면 순환 의존성이 좋지 않다고 말합니다.

1

다른 답변 외에 test.py를 스크립트로 실행하면 모듈 __main__입니다. 새 test 모듈을 만드는 distancefrom00.py에서 test.py을 가져올 때 주 스크립트에서 bar이고 distancefrom00.py에서 액세스 할 수있는 test.bar은 완전히 관련이 없습니다. 그들은 심지어 같은 클래스가 아닙니다 : 하나는 __main__.BarClass이고 다른 하나는 test.BarClass 인스턴스입니다.

그 이유는 두 개의 출력 15와 그 다음에 오는 10을 얻었 기 때문입니다. 메인 스크립트 barswitch 메서드가 호출되었지만 테스트 모듈 bar은 전환되지 않았습니다.

메인 스크립트를 다른 모듈로 가져 오는 과정은 고유 한 수준의 문제가 있습니다.