返回信息流代码想实现在类的方法上使用装饰器,装饰器里面新启线程去执行装饰的方法,但
t = threading.Thread(target=func, name='download')行报错,很纳闷,不知道如何修改。
self参数要如何加上?此时的func与self.download_active有什么区别?
### 代码如下
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import threading
class App():
def __init__(self):
pass
def download_thread(func):
def wrapper(self, *arg, **kw):
print(func)
print(self.download_active)
t = threading.Thread(target=func, name='download')
# TypeError: download_active() missing 1 required positional argument: 'self'
print('==============Ready to download=============')
t.start()
return
return wrapper
def download(self):
##### 此行在无装饰器下测试
t = threading.Thread(target=self.download_active, name='download')
t.start()
@download_thread
def download_active(self):
print('=== download_active ===')
def main():
app = App()
app.download_active()
pass
if __name__ == '__main__':
main()
os.system("pause")
pass
```
这是一条镜像帖。来源:北邮人论坛 / python / #16973同步于 2016/12/15
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Python机器人发帖
python 类的方法上使用装饰器
flymyheart
2016/12/15镜像同步11 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
def download_thread(func):
@wraps(func)
def wrapper(self, *arg, **kw):
print(func)
print(self.download_active)
t = threading.Thread(target=func(self), name='download')
# TypeError: download_active() missing 1 required positional argument: 'self'
print('==============Ready to download=============')
t.start()
return
return wrapper
其实我也不清楚为啥写成func(self),等待其他人的回复吧
这是func和self.download_active打印的结果
<function download_active at 0x02E23BF0>
<bound method App.download_active of <__main__.App instance at 0x02DF3670>>
ps:
个人习惯于把download_active写在类外面,给类添加__call__方法或者将download_thread改为@classmethod,不知这样处理是否满足楼主的设计思路
写成target=func(self)不对吧,那这句话的意思就变成先执行func(self),把结果传给target,这个过程的执行发生在线程开始之前。
我的目标是线程启动后才运行func函数
【 在 solosseason 的大作中提到: 】
: [code=python]
: def download_thread(func):
: @wraps(func)
: ...................
另外我也不是要简单写一个classMethod,我想实现对类中某些函数使用装饰器,用新线程去运行
【 在 solosseason 的大作中提到: 】
: [code=python]
: def download_thread(func):
: @wraps(func)
: ...................
【 在 flymyheart 的大作中提到: 】
: 写成target=func(self)不对吧,那这句话的意思就变成先执行func(self),把结果传给target,这个过程的执行发生在线程开始之前。
: 我的目标是线程启动后才运行func函数
嗯,不好意思,的确不对。你看这样改可以吗?
t = threading.Thread(target=func, name='download',args=(self,))
我是倾向于把class仅仅作为一个修饰器,保持单一性。
class App(object):
def __init__(self,func):
self._func = func
pass
def __call__(self):
print(self._func)
#print(self.download_active)
t = threading.Thread(target=self._func, name='download')
# TypeError: download_active() missing 1 required positional argument: 'self'
print('==============Ready to download=============')
t.start()
return
@App
def download_active():
print('=== download_active ===')
谢了,t = threading.Thread(target=func, name='download',args=(self,))这种方法可以,我对threading.Thread的参数还没仔细研究,这下好好看看
但类装饰器貌似不太适合我这个,download_active实际上是属于App类里面的操作,类似操作的有很多
(或者我没太理解你的意思?)
【 在 solosseason 的大作中提到: 】
: 嗯,不好意思,的确不对。你看这样改可以吗?
: [code=python]
: t = threading.Thread(target=func, name='download',args=(self,))
: ...................
在Python的类里面使用装饰器,这个装饰器对类方法的作用是在类还没有实例化的时候,所以没有绑定self。我认为解决办法一是显式传入self,二是在init中调用self.deco(self.func)来绑定self。
奇技淫巧有很多,但是应该把握根本原因~
嗯,谢谢,装饰器与self绑定的事儿我理解。按照我原来的程序,被装饰的函数和self的绑定关系是被装饰器破坏了的。
你说 “init中调用self.deco(self.func)来绑定self” 的事儿,是什么意思?deco还是装饰器么,多加入一个参数:def deco(self, func): 这个样子?这样做了,调用func时还是要传入self吧
【 在 asif12 的大作中提到: 】
: 在Python的类里面使用装饰器,这个装饰器对类方法的作用是在类还没有实例化的时候,所以没有绑定self。我认为解决办法一是显式传入self,二是在init中调用self.deco(self.func)来绑定self。
: 奇技淫巧有很多,但是应该把握根本原因~
Python中的装饰器归根结底只是语法糖,func函数在init中通过self.func引用会自动绑定self,这样再使用装饰器函数self.deco就是传入已经绑定self的func作为参数了
【 在 flymyheart 的大作中提到: 】
: 嗯,谢谢,装饰器与self绑定的事儿我理解。按照我原来的程序,被装饰的函数和self的绑定关系是被装饰器破坏了的。
: 你说 “init中调用self.deco(self.func)来绑定self” 的事儿,是什么意思?deco还是装饰器么,多加入一个参数:def deco(self, func): 这个样子?这样做了,调用func时还是要传入self吧
:
能给个具体例子么?
self.deco(self.f)是报错的,因为deoc只有一个参数。
如果写成AppTest.deco(self.f),t = threading.Thread(target=func, name='f')这句话仍然是没有绑定self的
```
class AppTest():
def __init__(self):
AppTest.deco(self.f)
pass
def deco(func):
def wrapper(self, *arg, **kw):
print('wrapper')
print(func)
func(self)
t = threading.Thread(target=func, name='f')
print('==============Ready to f=============')
t.start()
return
return wrapper
@deco
def f(self):
print('function')
```
【 在 asif12 的大作中提到: 】
: Python中的装饰器归根结底只是语法糖,func函数在init中通过self.func引用会自动绑定self,这样再使用装饰器函数self.deco就是传入已经绑定self的func作为参数了
: :