【问题标题】:Can two methods point to the same code?两种方法可以指向相同的代码吗?
【发布时间】:2018-10-20 23:44:57
【问题描述】:

我有一个公开两种方法的类。这些方法实际上是视觉语法糖,它们最终指向行为不同的相同代码,具体取决于它接收到的有效负载:

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')

但我想保留类方法的开/关结构。

【问题讨论】:

  • 如果actiononoff 以外的其他东西调用会发生什么?
  • “根据被调用方法的名称,其行为会有所不同”——这将是一个令人头疼的维护问题。你有什么问题?
  • 我没有发现你已经拥有的东西有什么问题...特别是考虑到onoff 的有效负载不同。
  • 一般来说,no Python 对象对绑定到它的名称(或名称)一无所知。你所拥有的是正确的方法。

标签: python python-2.7 class methods


【解决方案1】:

这与您的第一个示例非常相似,但您是否在寻找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)

然后,您的 actiononoff 函数都按预期工作:

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

使用partial 是一种语义更强的方式,可以说这是调用另一个函数的语法糖。诸如def on(self): ... 之类的函数声明可以是任何东西,而self.on = functools.partial(action,...) 明确声明您将一个函数绑定到另一个函数。

【讨论】:

    【解决方案2】:
    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)
    

    但我个人不喜欢这样,因为我的编辑不理解它并给了我错误的警告。

    【讨论】:

      【解决方案3】:

      试试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
      

      【讨论】:

      猜你喜欢
      • 2020-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多