Частичное наследование метода / декоратор в python - PullRequest
1 голос
/ 07 апреля 2020

Я заметил, что в моей функции у меня довольно много похожих строк кода в начале и в нижней части моих функций, например:

    def foo1():
        print('start')
        print('of ')
        print('a code')

        '''
        a lot of other code for the foo1
        '''

        print('end')
        print('of')
        print('the code')

    def foo2():
        print('start')
        print('of ')
        print('a code')

        '''
        a lot of other code for the foo2
        '''

        print('end')
        print('of')
        print('the code')

Я мог бы поместить подобные части разными способами как показано ниже:

def foo_init():
    print('start')
    print('of ')
    print('a code')

def foo_end():
    print('end')
    print('of')
    print('the code')


def foo1():
    foo_init()
    '''
    a lot of other code for the foo1
    '''
    foo_end():

def foo2():
    foo_init()
    '''
    a lot of the other for the foo1
    '''
    foo_end():

Так что мне интересно, есть ли какие-нибудь лучшие / более умные способы сделать это, возможно, с использованием наследования классов или для l oop?

Ответы [ 3 ]

3 голосов
/ 07 апреля 2020

Вы можете определить decorator

import functools
def inspect(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):

        print('start')
        print('of ')
        print('a code')

        value = func(*args, **kwargs)

        print('end')
        print('of')
        print('the code')

        return value
    return wrapper

Затем используйте его просто:

@inspect
def my_func ( arg ) :
    # Do something
    print( "my_func is called with arg =" , arg) 

Вы можете узнать больше и больше о декораторах: Учебник для начинающих на Python Декораторы

2 голосов
/ 07 апреля 2020

В дополнение к декоратору это вариант использования для менеджера контекста. Существует несколько способов определения диспетчера контекста, но я покажу тот, который позволяет использовать его в качестве декоратора.

from contextlib import ContextDecorator


class context(ContextDecorator):
    def __enter__(self):
        print('start')
        print('of ')
        print('a code')

    def __exit__(self, *exc):
        print('end')
        print('of')
        print('the code')

Затем вы можете написать либо

@context
def foo1():
    ...

или

def foo1():
    with context():
        ...

В зависимости от ваших конкретных потребностей c может быть более уместным использование диспетчера контекста или декоратора.

0 голосов
/ 07 апреля 2020

возможно с использованием наследования классов

В ОО это шаблон "метода шаблона":

class Base:
    def run(self, *args, **kw):
        print('start')
        print('of ')
        print('a code')

        value = self.method(*args, **kwargs)

        print('end')
        print('of')
        print('the code')

        return value


    def method(self, *args, **kw):
        return None


class Child(Base):
    def method(self, *args, **kw):
        return 42


c = Child()
c.run()

Но я бы не советовал использовать классы и наследование когда они вам не нужны.

...