سؤال

أنا أكتب نظامًا إضافيًا لبرنامجي ولا يمكنني تجاوز شيء واحد:

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

نظرت حولي وأنا ببساطة لا أعرف ما الذي يحدث.

هل كانت مفيدة؟

المحلول

"الفائق" مدمج.ما لم تكن قد بذلت قصارى جهدك لحذف العناصر المضمنة، فلن ترى أبدًا "الاسم العالمي 'super' غير محدد".

أنا أنظر إلى الخاص بك رابط الويب الخاص بالمستخدم حيث يوجد تفريغ IntrospectionHelper.من الصعب جدًا القراءة بدون المسافة البادئة، ولكن يبدو أنك قد تفعل ذلك بالضبط:

built_in_list = ['__builtins__', '__doc__', '__file__', '__name__']

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

هذه هي الوحدة الأصلية التي تقوم بتغييرها هناك، وليست نسخة إعلامية أنت على وشك إعادتها!احذف هؤلاء الأعضاء من الوحدة الحية، ويمكنك أن تتوقع انهيارًا أكثر من مجرد "ممتاز".

من الصعب جدًا متابعة ما تفعله هذه الوحدة، لكن رد فعلي هو أن هناك الكثير من السحر فيها.لا ينبغي أبدًا لبرنامج Python العادي أن يعبث بنظام الاستيراد، وsys.path، وأعضاء وحدة __magic__ الخاصة بتصحيح القرود.يمكن أن يكون القليل من السحر خدعة رائعة، لكنها هشة للغاية.من أعلى رأسي بعد تصفحه، يمكن كسر الكود بأشياء مثل:

  • يتعارض الاسم مع وحدات المستوى الأعلى
  • أي استخدام لفئات النمط الجديد
  • الوحدات المتوفرة فقط كرمز ثانوي تم تجميعه
  • com.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() هو بالتأكيد <لأ href = "http://docs.python.org/library/functions.html" يختلط = "نوفولو noreferrer "> المدمج في وظيفة (ويتوفر في كل مجال، وبدون استيراد أي شيء).

قد يكون تستحق التدقيق إصدار بيثون (بدء للتو موجه تفاعلي عن طريق كتابة بيثون في سطر الأوامر).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top