2009-03-04 4 views
2

내 프로그램에 대한 플러그인 시스템을 쓰고 있어요 내가 과거에 한 가지를 얻을 수 없습니다문제 (파이썬 2.5.2)

class ThingLoader(object): 
''' 
Loader class 
''' 

    def loadPlugins(self): 
     ''' 
     Get all the plugins from plugins folder 
     ''' 
     from diones.thingpad.plugin.IntrospectionHelper import loadClasses 

     classList=loadClasses('./plugins', IPlugin)#Gets a list of 
     #plugin classes 
     self.plugins={}#Dictionary that should be filled with 
     #touples of objects and theirs states, activated, deactivated. 
     classList[0](self)#Runs nicelly 
     foo = classList[1] 
     print foo#prints <class 'TestPlugin.TestPlugin'> 
     foo(self)#Raise an exception 

테스트 플러그인은 다음과 같습니다

import diones.thingpad.plugin.IPlugin as plugin 
    class TestPlugin(plugin.IPlugin): 
     ''' 
    classdocs 
    ''' 
    def __init__(self, loader): 
     self.name='Test Plugin' 
     super(TestPlugin, self).__init__(loader) 

이제 IPlugin은 다음과 같습니다

class IPlugin(object): 
    ''' 
    classdocs 
    ''' 
    name='' 
    def __init__(self, loader): 
     self.loader=loader 
    def activate(self): 
     pass 

모든 IPlugin 클래스

은 그들에 의해 flawlessy 작동 자아를하지만, ThingLoader 음식물에 의해 호출 할 때 숫양은 예외를 얻는다 :

File "./plugins\TestPlugin.py", line 13, in __init__ 
    super(TestPlugin, self).__init__(loader) NameError: 
global name 'super' is not defined 

나는 주변을 둘러 보았고 나는 무엇이 계속되고 있는지 간단히 알지 못한다.

+0

허용 된 답변을 읽은 후 불완전하고 오해의 소지가 있다는 질문에 대해 downvote를하고 싶습니다. –

답변

20

'super'는 내장되어 있습니다. 내장 명령을 삭제하지 않으면 "전역 이름 'super'가 정의되어 있지 않습니다.

나는 당신의 user web link에서 덤프되는 IntrospectionHelper를보고 있습니다. 그것은 들여 쓰기없이 읽을 매우 어렵습니다,하지만 당신은 정확하게 그 일을 할 수 것 같습니다 :

당신이 거기 변경하고 DICT 원래 모듈의
built_in_list = ['__builtins__', '__doc__', '__file__', '__name__'] 

for i in built_in_list: 
    if i in module.__dict__: 
     del module.__dict__[i] 

, 당신은 반환하려고하지 않은 정보를 복사! 라이브 모듈에서이 멤버를 삭제하면 '수퍼'보다 더 많은 것을 기대할 수 있습니다.

모듈이 무엇을하고 있는지 추적하는 것은 매우 어렵지만, 제 반응은 거기에 너무 많은 마술이 있습니다. 평범한 Python 프로그램은 import 시스템, sys.path 및 monkey-patching __magic__ 모듈 멤버를 사용하지 않아도됩니다. 약간의 마술은 깔끔한 트릭 일 수 있지만 이것은 매우 약합니다.

  • 모듈 전용으로 공급
  • 새로운 스타일의 클래스의 사용 최상위 모듈

    • 이름 충돌 : 그냥 검색에서 내 머리 위로 떨어져, 코드가 같은 것들에 의해 파괴 될 수있다 당신은 여전히 ​​시간의 기초에 대해 배울 수있는 꽤 가지고있는 것처럼 getClassDefinitions, extractModuleNames 및 isFromBase 같은 믿을 수 없을만큼 원형에 대한 기능에서

    , 그것은 나에게 보이는 zipimporter 바이트 코드

  • 컴파일 ow 파이썬이 작동합니다. (단서 : getattr, module .__ name__ 및 issubclass 각각)

    이 경우는 현재 이 아니며 임포트 마술로 다이빙을 할 시간입니다! 입니다. 대신, 일반적인 파이썬 방법을 사용하십시오. 이 패키지의 myPackage에/__ init__.py의 하단에 말을 조금 더 입력 할 수 있습니다

    from mypackage import fooplugin, barplugin, bazplugin 
    plugins= [fooplugin.FooPlugin, barplugin.BarPlugin, bazplugin.BazPlugin] 
    

    했지만 작동 것이다 복잡한, 깨지기 쉬운 마법의 둥지에 의존하지 않고 모든 곳에서 이해 될 수있다.

    덧붙여, 당신은 몇 가지 깊이있는 다중 상속 작업을 계획하고 (다시, 지금의 시간이 될 수 없습니다)하지 않는 한, 당신은 아마) (슈퍼를 사용할 필요가 없습니다. 일반적인 "IPlugin .__ init __ (self, ...) "알려진 수퍼 클래스를 호출하는 방법은 간단합니다. super()가 항상 "더 새로운, 일을하는 더 좋은 방법"이 아니며 there are things you should understand about it을 사용하기 전에 위탁합니다.

  • +2

    실제로 사용자 페이지 링크를 따라 코드 복사본을 찾아 디버깅하려면 +1하십시오. 이것은 가장 철저하게 연구 된 답변 중 하나 여야합니다. – DNS

    +0

    그는 상금을 받아야합니다! – Diones

    +0

    이 대답을 쓰는 것은 매우 즐겁습니다. +1 – nosklo

    0

    Python 2.2 이전 버전을 사용하고 있지 않다면, super()은 확실히 built-in function입니다 (모든 범위에서 사용할 수 있으며 아무 것도 가져 오지 않습니다).

    Python 버전을 확인하는 것이 좋습니다. 명령 행에서 python을 입력하여 대화식 프롬프트를 시작하십시오.