推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
just1
V2EX  ›  Python

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

  •  
  •   just1 · Jun 17, 2017 · 7167 views
    This topic created in 3337 days ago, the information mentioned may be changed or developed.

    原本想实现这样的功能

    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

    Supplement 1  ·  Jun 18, 2017
    #7,#14 的回复完美解决🌝我怎么没想到
    just1
        1
    just1  
    OP
       Jun 17, 2017
    = =在线等!!
    ipconfiger
        2
    ipconfiger  
       Jun 17, 2017   ❤️ 1
    头上无数黑线飘过
    1iuh
        3
    1iuh  
       Jun 17, 2017   ❤️ 1
    为什么要这样写装饰器?
    just1
        4
    just1  
    OP
       Jun 17, 2017 via Android
    @ipconfiger
    @1iuh TAT 能说说?
    XYxe
        5
    XYxe  
       Jun 17, 2017 via Android   ❤️ 1
    log 定义成静态方法或者类方法,然后 @ a.log
    1iuh
        6
    1iuh  
       Jun 17, 2017   ❤️ 1
    @just1 #4 你为什么要把装饰器放类里面呀?放类外面不就完了。你调用装饰器的时候用 self 肯定不对啊。
    phithon
        7
    phithon  
       Jun 17, 2017   ❤️ 1
    这样?
    ![image]( )
    1iuh
        8
    1iuh  
       Jun 17, 2017   ❤️ 1
    @just1 #4 你如果想取对象里面的变量,也不是这样写的。这个各种教程里面有说,我就不说了。
    just1
        9
    just1  
    OP
       Jun 17, 2017 via Android
    @1iuh 因为我需要把数据放进 class a 里面去啊 QAQ
    @XYxe 变成静态之后得把 a 对象传进去,跟我思路 1 一个问题。。
    just1
        10
    just1  
    OP
       Jun 17, 2017 via Android
    @phithon 😃对的就是这个效果😭居然没想到,谢谢!
    SP00F
        11
    SP00F  
       Jun 17, 2017
    ```
    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
        12
    SP00F  
       Jun 17, 2017
    @SP00F

    完。。。全错了
    tomwei7
        13
    tomwei7  
       Jun 17, 2017
    首先 python 装饰器是编译时执行的,而且 self 代表当前类的实例在调用类方法的时候作为第一个参数,self 只是一个约定成俗的写法
    SP00F
        14
    SP00F  
       Jun 17, 2017
    billion
        15
    billion  
       Jun 18, 2017
    XYxe
        16
    XYxe  
       Jun 18, 2017 via Android
    @just1 self 是在创建对象实例之后调用函数的时候才绑定的,所以在外面是不能用 self 的。改成静态函数,然后把 logs 属性按照类属性来用 a.logs.append 就可以。
    just1
        17
    just1  
    OP
       Jun 18, 2017 via Android
    @SP00F 哈哈跟#7 一样,谢谢回复
    @XYxe 对,我知道。所以我没这样用。。。
    just1
        18
    just1  
    OP
       Jun 18, 2017 via Android
    @tomwei7 懂的
    @billion 😂这个问题的点不在这里,我的代码里已经解决了这个问题
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   4365 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 10:01 · PVG 18:01 · LAX 03:01 · JFK 06:01
    ♥ Do have faith in what you're doing.