Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python2中的类方法钩子装饰器_Python - Fatal编程技术网

python2中的类方法钩子装饰器

python2中的类方法钩子装饰器,python,Python,我在用“post hook”函数装饰本机列表方法时遇到问题。我需要一个decorator,该decorator将本地列表方法作为参数,并且在调用该方法之后,它还应该运行被修饰的函数代码。 这段代码可以正常工作: def\u添加挂钩(clsmtd,信息fcn): def挂钩(s、*p、**k): ret=clsmtd(s,*p,**k) “这里发生了奇迹” 打印信息(s、*p、**k) 回程网 回程钩 def报告列表装饰(cls): def附加信息(s、*p、**k): 返回“附加到%s'%s.\

我在用“post hook”函数装饰本机列表方法时遇到问题。我需要一个decorator,该decorator将本地列表方法作为参数,并且在调用该方法之后,它还应该运行被修饰的函数代码。 这段代码可以正常工作:

def\u添加挂钩(clsmtd,信息fcn):
def挂钩(s、*p、**k):
ret=clsmtd(s,*p,**k)
“这里发生了奇迹”
打印信息(s、*p、**k)
回程网
回程钩
def报告列表装饰(cls):
def附加信息(s、*p、**k):
返回“附加到%s'%s.\u名称”
cls.append=\u add\u hook(cls.append,append\u info)
def删除信息(s、idx、*p、**k):
返回'removin%s[%s]'%(s.\u名称,idx)
cls.remove=\u添加\u钩子(cls.remove,remove\u信息)
def setitem_信息(s、idx、*p、**k):
返回'setitem%s[%s]'%(s.\u名称,idx)
cls.\uuuuuuu setitem\uuuuuuu=\u添加\u钩子(cls.\uuuuuuuuuuuuuu setitem\uuuuuuuuuuu,setitem\u信息)
''等等,也用于pop、排序、插入、反转和扩展''
返回cls
def测试报告列表():
@报告列表装饰
类报告列表(列表):
定义初始值(self,*p,**k):
super(reportin_list,self)。__init_(*p,**k)
self.\u name='foo'
rl=报告列表([6,6,6])
rl[1]=1
rl.追加(7)
rl.移除(1)
''输出:
setitem foo[1]
附加到foo
雷莫文福[1]
'''
但我想这样写:

def better_reporting_list_deco(cls):
    @_add_hook_for(cls.append)
    def append_info(s, *p, **k):
        return 'append to %s' % s._name

    @_add_hook_for(cls.remove)
    def remove_info(s, idx, *p, **k):
        return 'removin %s[%s]' % (s._name, idx) 

    @_add_hook_for(cls.__setitem__)
    def setitem_info(s, idx, *p, **k):
        return 'setitem %s[%s]' % (s._name, idx)

    return cls

问题是我不知道如何为装饰器编写
\u add\u hook\u。请给出建议。

写一个装饰工厂。您必须传入该类,否则无法可靠地检索该类(您传入的方法来自父类,因此即使我们设法检索上下文,也会使用错误的目标类):

然后,您的类装饰器变成:

def better_reporting_list_deco(cls):
    @_add_hook_for(cls, cls.append)
    def append_info(s, *p, **k):
        return 'append to %s' % s._name

    @_add_hook_for(cls, cls.remove)
    def remove_info(s, idx, *p, **k):
        return 'removing %s[%s]' % (s._name, idx) 

    @_add_hook_for(cls, cls.__setitem__)
    def setitem_info(s, idx, *p, **k):
        return 'setitem %s[%s]' % (s._name, idx)

    return cls
演示:


写一个装饰工厂。您必须传入该类,否则无法可靠地检索该类(您传入的方法来自父类,因此即使我们设法检索上下文,也会使用错误的目标类):

然后,您的类装饰器变成:

def better_reporting_list_deco(cls):
    @_add_hook_for(cls, cls.append)
    def append_info(s, *p, **k):
        return 'append to %s' % s._name

    @_add_hook_for(cls, cls.remove)
    def remove_info(s, idx, *p, **k):
        return 'removing %s[%s]' % (s._name, idx) 

    @_add_hook_for(cls, cls.__setitem__)
    def setitem_info(s, idx, *p, **k):
        return 'setitem %s[%s]' % (s._name, idx)

    return cls
演示:


感谢@martijn pieters,我这样重写了它(在Python 2.7中运行良好):

产出:

__setitem__ foo[1]
append foo
remove foo[1]
extend foo
pop foo[]
pop foo[2]
sort foo
__delitem__ foo[0]
reverse foo
[63, 61, 6] 

它也可以用于口述。谢谢你,Martijn

多亏了@martijn pieters,我才这样重写了它(在Python 2.7中运行良好):

产出:

__setitem__ foo[1]
append foo
remove foo[1]
extend foo
pop foo[]
pop foo[2]
sort foo
__delitem__ foo[0]
reverse foo
[63, 61, 6] 

它也可以用于口述。谢谢你,Martijn

你也许可以把它当作(cls,'append')
的“添加钩子”(add\u hook),因为这似乎是一个奇怪的装饰器用法。@jornsharpe:说得好。但是几乎每种本机方法都有不同的接口,报告函数采用不同的参数。这是否总是应用于内置类型?然后我就可以用Python 2和Python 3的相同代码来完成这项工作:-)@MartijnPieters:是的,它只适用于列表和目录。@Mikaelblomkvistsson:事实上,这个问题是没有意义的,因为这将是一个错误的目标,不适合插入装饰程序。你可以用
@\u add\u hook\u for(cls,'append')
,“这似乎是对装饰师的一种奇怪的使用。@jonrsharpe:说得好。但是几乎每种本机方法都有不同的接口,报告函数采用不同的参数。这是否总是应用于内置类型?然后我可以用同样的代码为Python 2和Python 3实现这一点:-)@MartijnPieters:是的,它只适用于列表和dict.@Mikaelblomkvistsson:事实上,这个问题没有意义,因为这是一个错误的目标。
__setitem__ foo[1]
append foo
remove foo[1]
extend foo
pop foo[]
pop foo[2]
sort foo
__delitem__ foo[0]
reverse foo
[63, 61, 6]