Могу ли я добавлять методы в класс по условию и вызывать их?

#python

#python

Вопрос:

Вот моя проблема:

  • У меня есть класс. И у меня есть два объекта этого класса: ObjectOne и ObjectTwo
  • Я бы хотел, чтобы в моем классе были определенные методы для ObjectOne и разные методы для ObjectTwo.
  • Я также хотел бы выбрать эти методы из множества в зависимости от некоторого условия.
  • и, конечно, мне нужно вызывать методы, которые у меня есть «из внешнего кода»

Поскольку я вижу решение самостоятельно (просто логика, без кода):

Я создаю класс по умолчанию. И я составляю список функций, определенных где-то. ЕСЛИ «некоторое условие» истинно, я создаю дочерний класс, который принимает одну из этих функций и добавляет ее в класс как метод класса. В противном случае я добавляю некоторый набор методов по умолчанию. Затем я создаю ObjectOne этого дочернего класса.

Вопрос в том, могу ли я вообще это сделать? И как мне это сделать? И как мне вызвать такой метод после его добавления? Все они, несомненно, будут называться по-разному…

Я не прошу здесь фрагмент рабочего кода. Если бы вы могли дать мне подсказку о том, где искать, или, может быть, определенную тему для изучения, это было бы просто отлично!

PS: На случай, если вам интересно, контекст таков: я создаю простой игровой прототип, и мои объекты представляют две игровые единицы (персонажи), которые сражаются друг с другом автоматически. Что-то вроде автоматической игры в шахматы. Каждый юнит может обладать уникальными способностями и поэтому должен действовать (принимать решения на поле боя) в зависимости от имеющихся у него способностей. Сначала я попытался создать единую процедуру принятия решений, которая включала бы все возможные возможности сразу (например: if hasDoubleStrike else if … и т.д.). Но это оказалось очень сложной задачей, потому что в целом существует десятки способностей, у каждого модуля могут быть любые две, так что количество комбинаций … огромно. Итак, теперь я пытаюсь распределить эту логику по отдельным блокам: каждый будет «знать» только о своих двух способностях.

Комментарии:

1. Похоже, вы описываете наследование классов .

2. у каждого дочернего класса должны быть свои собственные методы. вам не нужно добавлять их по условию. Предположим, что ClassA наследуется от Class. и иметь дополнительные методы, поддерживающие ClassA.

3. Честно говоря, это не очень хорошая идея. Те abilities , которые должны быть у ваших объектов, не должны быть методами, но, возможно, некоторые объекты, которые будут храниться в каком-либо атрибуте класса.

4. Прежде всего, вам следует прочитать о шаблоне проектирования заводских методов. Во-вторых, способность может быть представлена классом. И у вас может быть много подклассов этого класса. Используя объект factory, вы можете создать объект на основе некоторых условий.

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

Ответ №1:

Я имею в виду, я считаю, что это то, что обычно называют плохой идеей, но… вы могли бы передать аргумент в конструктор класса, а затем определить поведение / существование функции в зависимости от этого условия. Вот так:

 class foo():
    def __init__(self, condition):
        if condition:
            self.func = lambda : print('baz')
        else:
            self.func = lambda : print('bar')
    
if __name__ == '__main__':
    obj1 = foo(True)
    obj2 = foo(False)

    obj1.func()
    obj2.func()
 

Выводит:

 baz
bar
 

Вероятно, вам было бы лучше просто иметь разные классы или настроить какую-то иерархию классов.

Ответ №2:

Итак, в итоге лучшим решением был классический фабричный метод и фабричный класс. Вот так:

 import abc
import Actions     # a module that works as a library of standard actions


def make_creature(some_params):
    creature_factory = CreatureFactory()
    tempCreature = creature_factory.make_creature(some_params)
    return tempCreature


class CreatureFactory:
    def make_creature(some_params):
        ...
        if "foo" in some_params:
            return fooChildCreature()


class ParentCreature(metaclass=abc.ABCMeta):
    someStaticParams = 'abc'

    @abc.abstractmethod
    def decisionMaking():
        pass


class fooChildCreature(ParentCreature):
    def decisionMaking():
        Actions.foo_action()
        Actions.bar_action()
        # some creature-specific decision making here that calls same static functions from 'Actions'


NewCreature = make_creature(some_params)
 

Это не идеально, это все еще требует много ручной работы для определения принятия решений для различных видов существ, но это все равно намного лучше, чем что-либо еще. Большое вам спасибо за этот совет.