我正在尝试编写一个函数装饰器来测试x,y的边界
#这是我的绑定测试函数
def boundtest(func):
def onDecorator(self,x,y,* args,** kwargs):
打印(x,y,* args,** kwargs)
在range(self.width)中声明x,在range(self.height)中声明y
返回func(x,y,* args,** kwargs)
返回onDecorator
类游戏:
#这些是需要绑定检查的功能
@boundtest
def at(self,x:int,y:int)-> int:
返回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(最近一次通话结束):
中的文件“ C:\ Users \ Ben \ Desktop \ Projects \ bubble-breaker-bot \ game.py”,行61
game.set(1,1,Color.RED)
在onDecorator中的第21行,文件“ C:\ Users \ Ben \ Desktop \ Projects \ bubble-breaker-bot \ game.py”
返回func(x,y,* args,** kwargs)
TypeError:set()缺少1个必需的位置参数:“ data”
我需要boundtest函数来检查 x
和 y
是否在 self.width
和 self.height范围内
,同时能够将任意数量的参数传递给正在装饰的函数。
为什么会这样?
答案 0 :(得分:3)
装饰器应用于函数对象,而不应用于绑定方法。这意味着您需要手动传递self
参数:
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(self, x, y, *args, **kwargs)
return onDecorator
Python使用称为 binding 的过程将函数转换为绑定方法,并且调用绑定方法会自动将绑定到的内容作为第一个参数传递;这就是在实例上调用函数时将self
传递给方法的方式。有关详细信息,请参见Descriptor HowTo。您可以通过调用invoke descriptor binding manually来生成绑定方法,而无需手动传递self
,而是可以func.__get__()
:
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)
bound_method = func.__get__(self, type(self))
return bound_method(x, y, *args, **kwargs)
return onDecorator
该绑定行为应用于解析器在解决{{1}时返回的装饰器返回的onDecorator
函数对象,而不应用于包装的game.set
对象。