2014-01-12 1 views
1
에게

설정이 있다고 생각하지 않습니다 파이썬 3.3동적으로 수입 된 모듈은 클래스

내가 평 파일을 '소스'라는 폴더를 통해 보이는 응용 프로그램을 만들고 있어요, 그리고 확장하는 클래스를 찾기 위해 그들을 보면 내가 정의한 'SourceBase'라는 클래스. 만약 그들이 SourceBase를 확장한다면, 나는이 클래스의 새로운 인스턴스를 만들고 싶습니다.

내 폴더 설정을 :

이 나는 ​​대부분의 이해 다음과 같은 글을 통해 연구의 일부 상당한 양의 일을했습니다 나는 이것과 같다. 나는 경의를 표한다 :

EPDownloader [package] 
\ 
epdownloader.py [main] 
SourceBase.py [contains SourceBase class] 
imageutils.py [this class will find and dynamically load the classes in the sources package] 
sources [package] 
\ 
    source1.py [has class that extends SourceBase] 
    source2.py 
    ...other plugins here... 

내 문제는 내가 위에 나열된 다른 스택 오버플로 질문에서 다음 코드를 사용하고 클래스에 대한 내 모듈을 통해 검색하고 있지만 클래스를 찾을 수 없습니다. 그냥 건너 뜁니다. 나는 틀린 것이 확실하지 않다. 여기

<!--language: python--> 
def getSources(self): 
    pluginbase=SourceBase.SourceBase 
    searchpath='sources' 
    #We want to iterate over all modules in the sources/ directory, allowing the user to make their own. 
    for root, dirs, files in os.walk('./'+searchpath): 
     print('files: ',files) 
     candidates = [fname for fname in files if fname.endswith('.py') 
         and not fname.startswith('__')] 
     classList=[] 
     if candidates: 
      for c in candidates: 
       modname = os.path.splitext(c)[0] 
       print('importing: ',modname) 
       module=__import__(searchpath+'.'+modname) #<-- You can get the module this way 
       print('Parsing module '+modname) 
       for cls in dir(module):   #<-- Loop over all objects in the module's namespace 
        print('Inspecting item from module: '+str(cls)) 
        cls=getattr(module,cls) #this seems to still be a module when it hits source1 
        print('Get attribute: '+str(cls)) 
        if (inspect.isclass(cls)):    # Make sure it is a class 
         print('...is a class') 
         if inspect.getmodule(cls)==module: # Make sure it was defined in module, not just imported 
          print('...is in a module') 
          if issubclass(cls,pluginbase):   # Make sure it is a subclass of base 
           print('...subclasses '+pluginbase.__name__) 
           classList.append(cls) 
     print(classList) 

이 나를 제공 관련 출력 (I 다른 물건을 많이이 코드 출력을 손질) : 여기에 (내가 게시 된 첫 번째 링크 기반으로 자사) 검색을 수행하는 내 코드는

Inspecting item from module: source1 
Get attribute: <module 'sources.source1' from '/Users/Mgamerz/Documents/workspace/code/EPDownloader/sources/source1.py'> 
[] <--- signifies it failed to find the source class 

나는 나의 서브 클래스의 작품, 여기에 클래스의 코드 조각의 확신 :이 문제로 난처한 해요

from EPDownloader import SourceBase 
class source1(SourceBase.SourceBase): 
    def __init__(self): 
     pass 

. 나는 지난 몇 시간을 그것에 썼다. 그리고 나는 무엇을해야하는지 모른다. 나는 그것이 보이지 않는 간단한 고침을 느낍니다. 누군가 제가 여기서 버그를 찾도록 도와 줄 수 있습니까?

[참고 : StackOverflow 서식 지정 도움말을 살펴본 결과 텍스트에 회색 배경이 있지만 인라인은 '강조'형식으로 표시되지 않습니다. 내가 전달하기 위해 노력하고있어이 문제의 하이라이트 부분을 도움이 될] 문서에서

답변

2

봐 :. http://docs.python.org/3.1/library/functions.html#import

이름 변수는 일반적으로 양식 package.module이다, 리면를 이름이 인 모듈이 아닌 최상위 패키지 (이름에서 첫 번째 점까지)가 반환됩니다. 그러나 비어 있지 않은 fromlist 인수가 주어지면 name이라는 모듈이 반환됩니다.

는 단순히 안에 주어진 모듈을 모든 를 가져 __import__을 알려줍니다 "sources.source1 수입 *에서"로 동일합니다

module=__import__(searchpath+'.'+modname, None, None, "*") 

module=__import__(searchpath+'.'+modname) 

를 교체합니다.

+0

내가 좀 더 디버깅했다,하지만 soultion는 일 :

난 당신의 코드가이 일을 해결할 수 있습니다. 나는 몇 시간 동안 내 머리를 때리고있다. 감사. – Mgamerz

1

__import__에 문제가 있습니다. 모듈을 가져 오는 대신 전체 패키지 (전체 'sources'디렉토리를 패키지로 가져옴)를 가져옵니다.

for c in candidates: 
     modname = os.path.splitext(c)[0] 
     print('importing: ',modname) 
     # NEW CODE 
     sys.path.insert(0, searchpath) 
     module=__import__(modname) #<-- You can get the module this way 
     # END OF NEW CODE 
     print('Parsing module '+modname) 
     ... 
관련 문제