Могут ли два метода указывать на один и тот же код? - PullRequest
0 голосов
/ 10 мая 2018

У меня есть класс, который предоставляет два метода.Эти методы на самом деле являются визуальным синтаксическим сахаром, они в конечном итоге указывают на один и тот же код, который ведет себя по-разному, в зависимости от полезной нагрузки, которую он получает:

class Action:

    def on(self):
        self.action(1)

    def off(self):
        self.action(2)

    def action(self, payload):
        # a long function which does many things and uses the payload from on() and off()
        print(payload)

a = Action()
a.on()
a.off()

Есть ли способ определить on() и off() так, чтобыони указывают на один и тот же код (тот, что в action()), который будет вести себя по-разному в зависимости от имени метода, который был вызван?

Я, конечно, мог передать действие ввызов:

class Action:

    def action(self, what):
        payload = 1 if what == 'on' else 0
        # a long function which does many things and uses the payload from on() and off()
        print(payload)


a = Action()
a.action('on')
a.action('off')

но я хочу сохранить структуру on / off методов класса.

Ответы [ 3 ]

0 голосов
/ 10 мая 2018
def _action_maker(payload):
    def _action(self):
        return self.action(payload)

    return _action

class Action:
    on = _action_maker(1)
    off = _action_maker(2)

    def action(self, payload):
        # a long function which does many things and uses the payload from on() and off()
        print(payload)

Но лично мне это не нравится, потому что мой редактор не понимает этого и выдает мне ложные предупреждения.

0 голосов
/ 10 мая 2018

Это очень похоже на ваш первый пример, но вы ищете functools.partial ?

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

import functools
class Abc(object):
  def action(self, payload):
    print(payload)
  def __init__(self):
    self.off = functools.partial(self.action, payload=1)
    self.on = functools.partial(self.action, payload=2)

Затем у вас есть функции action, on и off, все работают как положено:

foo = Abc()
foo.on()
>>> 2
foo.off()
>>> 1
foo.action(9)
>>> 9

Использование partial является семантически более сильным способом сказать, что это синтаксический сахар для вызова другой функции.Объявление функции, такое как def on(self): ..., может быть любым, в то время как self.on = functools.partial(action,...) прямо заявляет, что вы связываете одну функцию с другой.

0 голосов
/ 10 мая 2018

Попробуйте inspect

import inspect
class Action:

    def on(self):
        self.action(1)

    def off(self):
        self.action(2)

    def action(self, payload):
        # a long function which does many things and uses the payload from on() and off()
        currentframe = inspect.currentframe()
        callername = inspect.getouterframes(currentframe, 2)[1][3]
        if callername =='on':
            print('on')
        elif callername == 'off':
            print('off')

a = Action()
a.on() #on
a.off() #off

Или просто передайте скрытый аргумент

class Action:

    def on(self):
        self.action(1,'on')

    def off(self):
        self.action(2, 'off')

    def action(self, payload, callername):
        # a long function which does many things and uses the payload from on() and off()
        if callername =='on':
            print('on')
        elif callername == 'off':
            print('off')

a = Action()
a.on() #on
a.off() #off
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...