Python class 里如何使用 self 的装饰器

2017-06-17 23:02:35 +08:00
 just1

原本想实现这样的功能

class a:
  logs=[]
  
  @self.log()
  def b():
    print('1')
    
  def log(self,text=''):
    def decorator(func):
      @functools.wraps(func)
      def wrapper(s, *args, **kw):
        self.logs.append(func,args,kw)
        return func(*args, **kw)
      return wrapper

    return decorator
  
  def redo(self):
    for _ in self.logs:
      _[0](*_[1],**_[2])
    

但这是错误的,@self.log()会报错 NameError: name 'self' is not defined 也想过把 log 拉出来,不放在 class a 里,有 2 个思路: 1.log 加一个 object 的参数,每次把这个 class 传进去 2.log()用 class 包裹起来,先初始化把 class a 传进去,后来调用就不用加 object 的参数了。

但是遇到问题 思路 1:@log(self)也是会报错 NameError: name 'self' is not defined 思路 2:没办法所有操作在 class a 内完成,没办法做成包调用

求助 QAQ

6553 次点击
所在节点    Python
19 条回复
just1
2017-06-17 23:13:09 +08:00
= =在线等!!
ipconfiger
2017-06-17 23:31:14 +08:00
头上无数黑线飘过
1iuh
2017-06-17 23:35:23 +08:00
为什么要这样写装饰器?
just1
2017-06-17 23:39:30 +08:00
@ipconfiger
@1iuh TAT 能说说?
XYxe
2017-06-17 23:40:22 +08:00
log 定义成静态方法或者类方法,然后 @ a.log
1iuh
2017-06-17 23:41:27 +08:00
@just1 #4 你为什么要把装饰器放类里面呀?放类外面不就完了。你调用装饰器的时候用 self 肯定不对啊。
phithon
2017-06-17 23:42:44 +08:00
这样?
![image]( )
1iuh
2017-06-17 23:43:24 +08:00
@just1 #4 你如果想取对象里面的变量,也不是这样写的。这个各种教程里面有说,我就不说了。
just1
2017-06-17 23:44:21 +08:00
@1iuh 因为我需要把数据放进 class a 里面去啊 QAQ
@XYxe 变成静态之后得把 a 对象传进去,跟我思路 1 一个问题。。
just1
2017-06-17 23:46:37 +08:00
@phithon 😃对的就是这个效果😭居然没想到,谢谢!
SP00F
2017-06-17 23:50:47 +08:00
```
import functools

def log():
def decorator(func):
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
self.logs.append([func, args, kwargs])
return func(self, *args, **kwargs)
return wrapper
return decorator

class a:
logs = []

@log()
def b(self, log):
print(1)


c = a()
c.b("ccc")
print(c.logs)
```


不知道是不是你需要的结果。。`self.logs.append(func,args,kw)` 这里也是不对的,列表在进行 append 操作的时候只能添加一个。。
SP00F
2017-06-17 23:51:24 +08:00
@SP00F

完。。。全错了
tomwei7
2017-06-17 23:51:40 +08:00
首先 python 装饰器是编译时执行的,而且 self 代表当前类的实例在调用类方法的时候作为第一个参数,self 只是一个约定成俗的写法
SP00F
2017-06-17 23:55:54 +08:00
billion
2017-06-18 00:02:45 +08:00
XYxe
2017-06-18 00:03:57 +08:00
@just1 self 是在创建对象实例之后调用函数的时候才绑定的,所以在外面是不能用 self 的。改成静态函数,然后把 logs 属性按照类属性来用 a.logs.append 就可以。
just1
2017-06-18 00:07:07 +08:00
@SP00F 哈哈跟#7 一样,谢谢回复
@XYxe 对,我知道。所以我没这样用。。。
just1
2017-06-18 00:08:39 +08:00
@tomwei7 懂的
@billion 😂这个问题的点不在这里,我的代码里已经解决了这个问题
sagaxu
2017-06-18 01:28:48 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/369212

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX