为什么python类方法’;s的第一个参数在用作装饰器时发生更改

为什么python类方法’;s的第一个参数在用作装饰器时发生更改,python,python-decorators,Python,Python Decorators,考虑以下代码: C类: def装饰器(自我): 打印(自我) def内部(*args): 返回自我(*args) 返回内部 @装饰师 def(自我): ... 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': c=c() c、 装饰器()#1 c、 装饰的#2 输出如下: <function C.decorated at 0x1121cd9d8> <__main__.C object at 0x111f5a8d0> 当deco

考虑以下代码:

C类:
def装饰器(自我):
打印(自我)
def内部(*args):
返回自我(*args)
返回内部
@装饰师
def(自我):
...
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
c=c()
c、 装饰器()#1
c、 装饰的#2
输出如下:

<function C.decorated at 0x1121cd9d8>
<__main__.C object at 0x111f5a8d0>

  • decorator
    函数作为普通类函数调用时,它收到的第一个参数是类实例
  • 但是,当调用
    decordent
    并将
    decorator
    函数用作decorator时,第一个参数是
    decordent
    函数;
    decorator
    函数现在的行为实际上与在类外定义的普通函数相同
  • 直观地说,由于
    decorator
    函数被定义为类内没有
    @staticmethod
    @classmethod
    decorator的函数,因此我认为它收到的第一个参数应该始终是类的实例。但事实并非如此


    我不经常看到这种编码模式,但是这种编码模式被广泛使用了吗?使用此编码模式可能存在哪些缺陷?

    我对您的代码做了一些更改,并试图解释注释中出现的情况:

    class C:
        def decorator(self, count=[0]):
            print(count, ":", self)
            count[0] += 1
            def inner(*args):
                return self(*args)
            return inner
    
        @decorator
        def decorated(self):
            print(self)
    
    if __name__ == '__main__':
        c = C() #0 Applies the decorator like
                #  decorated = decorator(decorated)
                #  Above, self equals decorated function, and gets printed
                #  inside decorator function.
                #  The decorated function is now a function that returns decorated(*args), actually None, but prints self, at call moment (not now).
        c.decorator() #1 normal bound method call, self is c
        print("[2] : ", end="") # for visual reference
        c.decorated() #2 calls C.decorated(c) so now self is c again and decorated is the result of decorated(c) that returns None but prints self (equals c), with no print from the decorator bound method, that does not run.
    
    产出:

    [0] : <function C.decorated at 0x7f26945b4ee0>
    [1] : <__main__.C object at 0x7f26945bddc0>
    [2] : <__main__.C object at 0x7f26945bddc0>
    
    [0]:
    [1] : 
    [2] : 
    

    我认为这个用法有点混乱,所以除非你有具体的理由这么做。。。然而,我看到了一些高级代码,其中包含装饰器或元类,很难掌握。这始终是一个真正需要有价值的东西的问题。我建议您搜索典型的decorator和类decorator用法。罕见的外观与广泛使用的不同。

    我对您的代码做了一些更改,并试图解释注释中发生的情况:

    class C:
        def decorator(self, count=[0]):
            print(count, ":", self)
            count[0] += 1
            def inner(*args):
                return self(*args)
            return inner
    
        @decorator
        def decorated(self):
            print(self)
    
    if __name__ == '__main__':
        c = C() #0 Applies the decorator like
                #  decorated = decorator(decorated)
                #  Above, self equals decorated function, and gets printed
                #  inside decorator function.
                #  The decorated function is now a function that returns decorated(*args), actually None, but prints self, at call moment (not now).
        c.decorator() #1 normal bound method call, self is c
        print("[2] : ", end="") # for visual reference
        c.decorated() #2 calls C.decorated(c) so now self is c again and decorated is the result of decorated(c) that returns None but prints self (equals c), with no print from the decorator bound method, that does not run.
    
    产出:

    [0] : <function C.decorated at 0x7f26945b4ee0>
    [1] : <__main__.C object at 0x7f26945bddc0>
    [2] : <__main__.C object at 0x7f26945bddc0>
    
    [0]:
    [1] : 
    [2] : 
    
    我认为这个用法有点混乱,所以除非你有具体的理由这么做。。。然而,我看到了一些高级代码,其中包含装饰器或元类,很难掌握。这始终是一个真正需要有价值的东西的问题。我建议您搜索典型的decorator和类decorator用法。很少见到的与广泛使用的看起来不同。

    看起来“问题”其实在初始阶段

    class C:
        def decorator(self):
            print(self)
            def inner(*args):
                return self(*args)
            return inner
        @decorator
        def decorated(self):
            pass
    if __name__ == '__main__':
        c = C()
        #c.decorator() # 1
        #c.decorated() #2
    
    python test.py

    <function C.decorated at 0x00000289DD5BE160>
    
    
    
    所以。。。在具有修饰函数的类的init处,它首先修改函数(以启动修饰器而不是修饰函数)。 可能有一些文档可以阅读。我从来没有在类中使用过decorator,只是单独使用。

    看起来“问题”其实在init

    class C:
        def decorator(self):
            print(self)
            def inner(*args):
                return self(*args)
            return inner
        @decorator
        def decorated(self):
            pass
    if __name__ == '__main__':
        c = C()
        #c.decorator() # 1
        #c.decorated() #2
    
    python test.py

    <function C.decorated at 0x00000289DD5BE160>
    
    
    
    所以。。。在具有修饰函数的类的init处,它首先修改函数(以启动修饰器而不是修饰函数)。 可能有一些文档可以阅读。我从来没有在课堂上使用过装饰师,只是单独使用