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

类内的(Micro)Python回调函数抛出类型错误

  •  0
  • Daniel  · 技术社区  · 1 年前

    我或多或少是Python的新手,在OOP(来自C而不是C++)方面仍有点吃力。 我想重用和扩展一个旋转编码器类,只想添加一个带有中断回调例程的开关。但它总是抛出一个错误:

    from rotary_encoder.rotary_irq_esp import RotaryIRQ
    from machine import Pin
    
    
    
    class RotaryEncoder(RotaryIRQ):
      # rotary options
      RANGE_MODE = const(1) # 1->UNBOUNDED, 2->WRAP, 3->BOUNDED
      PIN_CLK = const(7)
      PIN_DT = const(8)
      PULL_UP = True
    
      # switch options
      PIN_SWITCH = const(6)
      PULL_UP_SWITCH = True
      
      def __init__(self, pin_num_clk=PIN_CLK, pin_num_dt=PIN_DT, min_val=0, max_val=10, incr=1,range_mode=RANGE_MODE, pull_up=PULL_UP,pin_switch=PIN_SWITCH,pull_up_switch=PULL_UP_SWITCH):
        super().__init__(pin_num_clk, pin_num_dt, min_val, max_val, incr, range_mode, pull_up)
        # add switch
        if pull_up_switch:
          self.switch = Pin(pin_switch,Pin.IN, Pin.PULL_UP)
          self.switch.irq(trigger=Pin.IRQ_FALLING, handler=self._rotary_switch_callback)
        else:
          self.switch = Pin(pin_switch,Pin.IN, Pin.PULL_DOWN)
          self.switch.irq(trigger=Pin.IRQ_RISING, handler=self._rotary_switch_callback)
    
      def _rotary_switch_callback(self):
        pass
    

    你知道为什么它不起作用吗??

    错误为: TypeError:函数接受1个位置参数,但给定了2个

    我试了好几种方法,但都没用。 在另一个组件中,我看到了一个没有(self)参数的类中的回调函数定义。这在这里也不起作用(顺便说一句,我很困惑为什么类中的函数不是静态方法或类方法,而没有(self)参数-但这是另一个主题:-)

    我试过了

    handler=self._rotary_switch_callback)
    handler=_rotary_switch_callback)
    
    def _rotary_switch_callback(self):
    def _rotary_switch_callback():
    
    

    如果我在类之外使用代码,它是有效的,但另一个参数是实例本身。不知道我该如何把这个转移到课堂上。

    def rotary_switch_callback(rotary_switch):
       pass 
    rotary_switch = Pin(6,Pin.IN, Pin.PULL_UP)
    rotary_switch.irq(trigger=Pin.IRQ_FALLING, handler=rotary_switch_callback)
    

    如果我执行以下操作,它(当然)不起作用:-)

    self.switch = Pin(pin_switch,Pin.IN, Pin.PULL_DOWN)
    self.switch.irq(trigger=Pin.IRQ_RISING, handler=self._rotary_switch_callback)
    
    def _rotary_switch_callback(self, self.switch):
      pass
    

    我不知道为什么它不起作用,但我认为如果实例本身就是自变量,我就不能给出instance.instance作为自变量。你知道我如何在不使用丑陋伎俩的情况下以“正确”的方式解决这个问题吗?

    2 回复  |  直到 1 年前
        1
  •  1
  •   Coding Enthusiast    1 年前

    根据MicroPython文档:

    handler is an optional function to be called when the interrupt triggers. The handler must take exactly one argument which is the Pin instance.
    

    这意味着处理程序函数必须接受一个参数,该参数将是触发中断的Pin实例。

    当您设置这样的中断时:

    self.switch.irq(trigger=Pin.IRQ_RISING, handler=self._rotary_switch_callback)
    

    处理程序函数需要两个参数:self和Pin实例。(self-argument隐含在实例方法中。)

    所以,你需要修改你的 _rotary_switch_callback 方法接受Pin实例作为参数:

    def _rotary_switch_callback(self, pin):
        pass
    
        2
  •  0
  •   furas    1 年前

    我不知道是什么 self.switch.irq() 但它似乎用一些额外的参数来执行您的函数,例如 PIN -你必须得到它

    def _rotary_switch_callback(self, parameter):
    

    如果你不知道它会发送多少个参数,也不知道它是定位参数还是命名参数,那么你可以使用流行的 *args, **kwargs

    def _rotary_switch_callback(self, *args, **kwargs):
        print('args:', args)
        print('kwargs:', kwargs)
    

    但是您应该在文档中有关于参数的信息。