代码之家  ›  专栏  ›  技术社区  ›  WoJ

两个方法可以指向相同的代码吗?

  •  0
  • WoJ  · 技术社区  · 7 年前

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

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

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

    3 回复  |  直到 7 年前
        1
  •  1
  •   Scott Mermelstein    7 年前

    这与您的第一个示例非常相似,但您正在寻找 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,...) 明确声明将一个函数绑定到另一个函数。

        2
  •  0
  •   Alex Hall    7 年前
    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
  •  -1
  •   Ken T    7 年前

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