Super를 사용하는 문제 (Python 2.5.2)
-
03-07-2019 - |
문제
프로그램을위한 플러그인 시스템을 작성하고 있는데 한 가지를 지나칠 수 없습니다.
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 클래스는 그들 자신에 의해 완벽하게 작동하지만 ThingLoader에 의해 호출되면 프로그램은 예외를 얻습니다.
File "./plugins\TestPlugin.py", line 13, in __init__
super(TestPlugin, self).__init__(loader) NameError:
global name 'super' is not defined
나는 모든 것을 보았고 단순히 무슨 일이 일어나고 있는지 모른다.
해결책
'슈퍼'는 내장 된 것입니다. 빌드 딘을 삭제하는 길을 벗어나지 않으면“글로벌 이름 '슈퍼'가 정의되지 않은 것을 보지 않아야합니다.
나는 당신을보고 있습니다 사용자 웹 링크 introspectionHelper의 덤프가있는 곳. 들여 쓰기없이 읽기가 매우 어렵지만 정확히 그렇게하는 것처럼 보입니다.
built_in_list = ['__builtins__', '__doc__', '__file__', '__name__']
for i in built_in_list:
if i in module.__dict__:
del module.__dict__[i]
그것은 당신이 바꾸는 원래 모듈 dict입니다. 당신이 돌아올 정보 사본이 아닙니다! 라이브 모듈 에서이 멤버를 삭제하면 '슈퍼'이상의 부분이 깨질 것으로 기대할 수 있습니다.
그 모듈이 무엇을하고 있는지 추적하는 것은 매우 어렵지만, 내 반응은 너무 많은 마법이 있다는 것입니다. 평균 Python 프로그램은 수입 시스템, Sys.Path 및 Monkey-Patching __Magic__ 모듈 멤버를 망쳐 놓을 필요가 없습니다. 약간의 마법은 깔끔한 속임수 일 수 있지만 이것은 매우 깨지기 쉽습니다. 내 머리 꼭대기에서 탐색하는 것에서 코드는 다음과 같은 것들에 의해 깨질 수 있습니다.
- 이름은 최상위 모듈과 충돌합니다
- 새로운 스타일의 수업을 사용합니다
- 모듈은 바이오 코드로 컴파일 된 것으로만 제공됩니다
- zipimporter
GetClassDefinitions, ExtractModulenames 및 Isfrombase와 같은 엄청나게 원형 기능에서 Python의 작동 방식의 기본 사항에 대해 배우는 것이 여전히 나에게 보입니다. (단서 : getAttr, module .__ name__ 및 issubclass.)
이 경우 지금은입니다 ~ 아니다 수입 마법으로 뛰어들 시간! 이것의 딱딱한. 대신, 정상적인 파이썬 방식으로 일을하십시오. 패키지의 MyPackage/__ init__.py의 하단에서 말하는 것이 조금 더 타이핑 할 수 있습니다.
from mypackage import fooplugin, barplugin, bazplugin
plugins= [fooplugin.FooPlugin, barplugin.BarPlugin, bazplugin.BazPlugin]
그러나 복잡하고 깨지기 쉬운 마법의 둥지에 의존하지 않고는 작동하고 모든 곳에서 이해 될 것입니다.
또한, 심층적 인 여러 상속 작업을 계획하지 않는 한 (이제 다시는 그 시간이 아닐 수도 있음) Super ()를 사용할 필요조차 없습니다. 알려진 슈퍼 클래스를 호출하는 일반적인 "iplugin .__ init __ (self, ...)"방법은 간단한 일입니다. Super ()는 항상 "새롭고 더 나은 일을하는 방법"은 아닙니다. 그것에 대해 이해해야 할 것이 있습니다 사용하기 전에 사용하기 전에.
다른 팁
2.2보다 일찍 파이썬 버전을 실행하지 않는 한 super()
확실히 a 내장 기능 (모든 범위에서 그리고 가져 오지 않고 사용할 수 있습니다).
Python 버전을 확인하는 것이 좋습니다 (명령 줄에서 Python을 입력하여 대화식 프롬프트를 시작하십시오).