python مكتبة بيثون: تزيين أسلوب الفئة التي تهدف إلى الكتابة فوق عند الموروثة



مكتبة اكواد بايثون (1)

وكما هو مقترح في التعليقات، فإن السماح للفئات الفرعية بتجاوز الخطاف بدلا من run نفسه ربما يكون أفضل:

class Task(object):
    def run(self):
        # before 
        self.do_run()
        # after

class MyTask(Task):
    def do_run(self):
        ...

task = MyTask()
task.run()

ومع ذلك، هذه هي الطريقة الوحيدة التي يمكن أن تفعل ذلك مع ديكور الطبقة:

def decorate_run(cls):
    run = getattr(cls, 'run')
    def new_run(self):
        print('before')
        run(self)
        print('after')
    setattr(cls, 'run', new_run)
    return cls


class Task(object): pass

@decorate_run
class MyTask(Task):
    def run(self):
        pass

task = MyTask()
task.run()

# prints:
# before
# after

وهناك طريقة أخرى لاستخدام ميتاكلاس. ميزة استخدام ميتاكلاس سيكون أن الفئات الفرعية لا يجب أن تكون مزينة. يمكن إجراء Task مثيل ميتاسكلاس، ثم كل الفئات الفرعية من Task سيرث ميتاكلاس تلقائيا.

class MetaTask(type):
    def __init__(cls, name, bases, clsdict):
        if 'run' in clsdict:
            def new_run(self):
                print('before')
                clsdict['run'](self)
                print('after')
            setattr(cls, 'run', new_run)

class Task(object, metaclass=MetaTask):
    # For Python2: remove metaclass=MetaTask above and uncomment below:
    # __metaclass__ = MetaTask
    pass

class MyTask(Task):
    def run(self):
        #successful override!
        pass

task = MyTask()
task.run()

لنفترض أن لدي فئة أساسية:

class Task:
    def run(self):
        #override this!

الآن، أريد الآخرين إلى الفئة الفرعية المهمة وتجاوز طريقة التشغيل ():

class MyTask(Task):
    def run(self):
        #successful override!

ومع ذلك، فإن المشكلة هي أن هناك منطق يجب أن يتم قبل وبعد تشغيل () طريقة كل فئة الفئات الفرعية المهمة.

يبدو أن هناك طريقة واحدة يمكن أن أفعلها هذه هي تحديد طريقة أخرى في فئة القاعدة التي تستدعي بعد ذلك طريقة التشغيل (). ومع ذلك، أردت أن أسأل، هل هناك طريقة لتحقيق ذلك مع الديكور؟ ما هي الطريقة الأكثر بيثونيك للقيام بذلك؟





decorator