0

什么是正确的语法?

编程尝试

class Foo:
    def hello(self):
        print "Hello cruel world!"
 
    def greet_first(self, f):
        self.hello()
        return lambda *args, **kwargs: f(*args, **kwargs)
 
    @greet_first
    def goodbye(self, concat):
        print "Goodbye {0}".format(concat)
 
if __name__=='__main__':
    bar = Foo()
    bar.goodbye(' and thanks for all the fish')

调试

Traceback (most recent call last):
  File "prog.py", line 1, in <module>
    class Foo:
  File "prog.py", line 9, in Foo
    @greet_first
TypeError: greet_first() takes exactly 2 arguments (1 given)

参考

点击运行代码(IDEone)

4

1 回答 1

2

装饰器被立即调用,它不被视为方法,Foo而是被视为本地函数。@greet_first语法有效地意味着:

 goodbye = greet_first(goodbye)

立即执行。它不是绑定方法,因此self不包含参数。制定方法是没有意义greet_first的。将其移出并self完全删除论点。

您需要调整装饰器以返回可调用的 replace goodbye

def greet_first(f):
    def wrapper(self, *args, **kwargs):
        self.hello()
        return f(self, *args, **kwargs)
    return wrapper

所以self.hello()每次goodbye都调用它。

如果你必须成为greet_first的一部分Foo,你可以使用@staticmethod装饰器,但你必须跳过一个额外的圈才能将它用于其他方法声明;您必须将其视为已成为的描述符并调用.__get__()它:

class Foo(object):
    def hello(self):
        print "Hello cruel world!"

    @staticmethod
    def greet_first(f):
        def wrapper(self, *args, **kwargs):
            self.hello()
            return f(self, *args, **kwargs)
        return wrapper

    @greet_first.__get__(object)
    def goodbye(self, concat):
        print "Goodbye {0}".format(concat)

.__get__()使用任意类型(object在这种情况下)调用,因为无论如何都会staticmethod 忽略该参数;我们不能Foo在这里使用,因为该类在作为其定义的一部分的代码中尚未最终确定。

请注意,@staticmethod为了工作,您需要从objectPython 2 继承。

于 2013-02-09T13:11:54.290 回答