猿问

函数修饰器引发位置参数错误?

我正在尝试编写一个函数装饰器来测试x,y的范围


#this is my bound test function

def boundtest(func):

    def onDecorator(self, x, y, *args, **kwargs):

        print(x, y, *args, **kwargs)

        assert x in range(self.width) and y in range(self.height)

        return func(x, y, *args, **kwargs)


    return onDecorator


class Game:

    #these are the functions that need bound checking


    @boundtest

    def at(self, x: int, y: int) -> int:

        return self.map[x, y]


    @boundtest

    def set(self, x: int, y: int, data):

        self.map[x, y] = data.value

当我执行时,game.set(1, 1, Color.RED)我得到:


Traceback (most recent call last):

  File "C:\Users\Ben\Desktop\Projects\bubble-breaker-bot\game.py", line 61, in <module>

    game.set(1, 1, Color.RED)

  File "C:\Users\Ben\Desktop\Projects\bubble-breaker-bot\game.py", line 21, in onDecorator

    return func(x, y, *args, **kwargs)

TypeError: set() missing 1 required positional argument: 'data'

我需要boundtest函数来检查x和y分别在和的范围内self.width,self.height同时能够将任意数量的参数传递给它正在装饰的函数。


为什么会这样?


月关宝盒
浏览 146回答 1
1回答

喵喔喔

装饰器应用于函数对象,而不应用于绑定方法。这意味着您需要手动传递self参数:def boundtest(func):&nbsp; &nbsp; def onDecorator(self, x, y, *args, **kwargs):&nbsp; &nbsp; &nbsp; &nbsp; print(x, y, *args, **kwargs)&nbsp; &nbsp; &nbsp; &nbsp; assert x in range(self.width) and y in range(self.height)&nbsp; &nbsp; &nbsp; &nbsp; return func(self, x, y, *args, **kwargs)&nbsp; &nbsp; return onDecoratorPython使用一个称为绑定的过程将一个函数转换为一个绑定方法,调用绑定方法会自动将绑定的内容作为第一个参数传递给它。self当您在实例上调用函数时,这就是如何传递给方法的。有关详细信息,请参见描述符HowTo。除了手动传递外self,您还可以通过调用生成绑定方法来手动调用描述符绑定func.__get__():def boundtest(func):&nbsp; &nbsp; def onDecorator(self, x, y, *args, **kwargs):&nbsp; &nbsp; &nbsp; &nbsp; print(x, y, *args, **kwargs)&nbsp; &nbsp; &nbsp; &nbsp; assert x in range(self.width) and y in range(self.height)&nbsp; &nbsp; &nbsp; &nbsp; bound_method = func.__get__(self, type(self))&nbsp; &nbsp; &nbsp; &nbsp; return bound_method(x, y, *args, **kwargs)&nbsp; &nbsp; return onDecorator该绑定行为应用于onDecorator解析器game.set在解析时返回的功能对象,而不应用于包装的func对象。
随时随地看视频慕课网APP

相关分类

Python
我要回答