WedX - журнал о программировании и компьютерных науках

Запуск определенного набора методов подклассов без их явного вызова

Я реализую в Python следующее: (скелет кода ниже)

    class Base(object):

        def __init__(self, run_ext):
        def common_method1(self, run_ext):
        def common_method2(self, run_ext):


        def run_all(self):
             """Run all the methods beginning with run*"""  

    class Ext1(Base):

        def run11(self):
        def run12(self):

        def notrelated11(self):


    class Ext2(Base):

        def run21(self):
        def run22(self):

        def notrelated21(self):


Ext1.run_all()  # should run all the *'run*'* methods in Ext1 and 
Ext2.run_all()  # should run all the *'run*'* methods in Ext2.

Цель: реализация run_all() в базовом классе, который запускал бы определенный набор методов из подкласса при вызове.

Мысли: - Ванильный способ сделать это - сделать явные вызовы методов в подклассах и определить run_all в родительском классе как абстрактный метод. - Несколько хакерский способ - установка атрибута (или идентификация методов, которые должны быть запущены, по их именам).

Я ищу любые лучшие альтернативные решения.

  • Также хотелось бы знать, соответствует ли эта проблема какому-либо существующему шаблону проектирования?

Примечание. Дочерние классы могут содержать другие методы, кроме методов run1, run2 и т. д., упомянутых выше методов not_related.

Обновление: как указал @mkriheli, базовый класс не должен/не должен знать о дочерних классах, унаследованных от него.

Спасибо.

07.08.2014

  • Вы забыли себя при вызове методов запуска (self.run1()...). 07.08.2014
  • Ну, я думаю, что run1() и run2() могут быть объявлены в суперклассе, а затем перегружены, поскольку они имеют одно и то же имя и появляются в обоих дочерних классах. Если это не совпадение (если это так, измените их имена, так как это может сбить с толку). 07.08.2014
  • Это плохой дизайн, класс не должен знать о наследовании от него. 07.08.2014
  • методы подклассов будут другими. Спасибо, что указали. 07.08.2014
  • @mkriheli это хороший момент. 07.08.2014
  • Я предпочитаю использовать декораторы, так как они более чистые и питонические. Но если вы настаиваете на этом, возможно, вы можете использовать self.__class__.__dict__, который даст вам все вещи из класса, среди которых вы можете найти функции. 07.08.2014

Ответы:


1

Как насчет использования декораторов:

import inspect

def runnable(f):
  setattr(f, '__can_run__', True)
  return f

class Base:
  def run_all(self):
    for runner_name in inspect.getmembers(self, predicate=inspect.ismethod):
      func = getattr(self, runner_name[0])
      if hasattr(func, '__can_run__'):
        if getattr(func, '__can_run__'):
          func()

class Child(Base):
  def __init__(self):
    self.incremental = 0

  @runnable
  def run1(self):
    self.incremental += 1
    print "running", self.incremental

  @runnable
  def run2(self):
    self.incremental += 1    
    print "running", self.incremental


c = Child()
c.run_all()

Выход:

running 1
running 2

Обратите внимание, что я не рекомендую использовать inspect, и то, что вы пытаетесь сделать, может быть лучше. inspect — это функция реализации CPython, и ее присутствие в других реализациях Python не гарантируется. Не делайте Wrong Thing To Do.

07.08.2014
  • Я использую реализацию CPython, и это хороший способ выполнить работу, но я ищу более простое/тонкое решение. 07.08.2014

  • 2

    Следуя идее @Nandeep, альтернатива без проверки

    class runnable(object):
      run_list = []
      @staticmethod
      def add(f):
        runnable.run_list.append(f)
    
    class Base:
      def run_all(self):
        for runner_name in runnable.run_list:
          # Now you have all the functions
    
    
    class Child(Base):
      def __init__(self):
        self.incremental = 0
    
      @runnable.add
      def run1(self):
        self.incremental += 1
        print "running", self.incremental
    
    07.08.2014
  • Не вызовут ли проблемы несколько дочерних элементов, добавляющих «runnables» к этому статическому классу? Потому что все они добавляют к одному и тому же run_list. 17.08.2014
  • Новые материалы

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..


    Для любых предложений по сайту: [email protected]