python补充学习
thread
_thread
调用 _thread 模块中的start_new_thread()函数来产生新线程。
_thread.start_new_thread ( function, args[, kwargs] )
参数说明:
- function - 线程函数。
- args - 传递给线程函数的参数,他必须是个tuple类型。
- kwargs - 可选参数。
#!/usr/bin/python3
import _thread
import time
# 为线程定义一个函数
def print_time( threadName, delay):
count = 0
while count < 5:
time.sleep(delay)
count += 1
print ("%s: %s" % ( threadName, time.ctime(time.time()) ))
# 创建两个线程
try:
_thread.start_new_thread( print_time, ("Thread-1", 2, ) )
_thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
print ("Error: 无法启动线程")
while 1:
pass
threading
threading 模块除了包含 _thread 模块中的所有方法外,还提供的其他方法:
- threading.currentThread(): 返回当前的线程变量。
- threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
- threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法:
- run(): 用以表示线程活动的方法。
- start():启动线程活动。
- join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
- isAlive(): 返回线程是否活动的。
- getName(): 返回线程名。
- setName(): 设置线程名。
https://blog.csdn.net/hzp666/article/details/78948998
1 python 默认参数创建线程后,不管主线程是否执行完毕,都会等待子线程执行完毕才一起退出,有无join结果一样
2 如果创建线程,并且设置了daemon为true,即thread.setDaemon(True), 则主线程执行完毕后自动退出,不会等待子线程的执行结果。而且随着主线程退出,子线程也消亡。
setDaemon(True),——正是这个方法防止子线程无限执行下去,保证主线程终止,子线程也终止。加了join方法后,主线程会等待子线程timeout时间后再终止,
3 join方法的作用是阻塞,等待子线程结束,join方法有一个参数是timeout,即如果主线程等待timeout,子线程还没有结束,则主线程强制结束子线程。
4 如果线程daemon属性为False, 则join里的timeout参数无效。主线程会一直等待子线程结束。
5 如果线程daemon属性为True, 则join里的timeout参数是有效的, 主线程会等待timeout时间后,结束子线程。此处有一个坑,即如果同时有N个子线程join(timeout),那么实际上主线程会等待的超时时间最长为 N * timeout, 因为每个子线程的超时开始时刻是上一个子线程超时结束的时刻。
【是子线程】
使用示例:
https://blog.csdn.net/zzzzjh/article/details/80614897
一般:先循环新建,加入thread列表里
再循环start-》启动
再循环join-》等待运行结束
再循环得到运行结果 getresult
@的使用
#funA 作为装饰器函数
def funA(fn):
#...
fn() # 执行传入的fn参数
#...
return '...'
@funA
def funB():
#...
等价于:
def funA(fn):
#...
fn() # 执行传入的fn参数
#...
return '...'
def funB():
#...
funB = funA(funB)
上面示例中,都是使用一个装饰器的情况,但实际上,Python 也支持多个装饰器,比如:
@funA
@funB
@funC
def fun():
#...
上面程序的执行顺序是里到外,所以它等效于下面这行代码:
fun = funA( funB ( funC (fun) ) )
python 装饰器
装饰器本身是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。
装饰器的作用是为已经存在的对象添加额外的功能。
如何理解Python装饰器? - NET.Dzreal的回答 - 知乎 https://www.zhihu.com/question/26930016/answer/1047233982
装饰器 神奇!
global
https://blog.csdn.net/weixin_40894921/article/details/88528159
Python中定义函数时,若想在函数内部对函数外的变量进行操作,就需要在函数内部声明其为global。
https://www.cnblogs.com/walxt/p/11484699.html
有时候我们需要在我们的函数中调用全局变量的值,此时我们需要对该变量用global重新声明
global语句的使用方法很简单,基本格式是:
关键字global,后跟一个或多个变量名
https://www.jianshu.com/p/eac98fd2c54b
变量作用域
先要明确作用域的概念,定义在函数内部的变量拥有一个局部作用域,而定义在函数外的拥有全局作用域。
a = 5 # 这是一个全局变量
def hello():
a = 1 # a在这里是局部变量.
print("函数内是局部变量 : ", a)
return a
hello()
print("函数外是全局变量 : ", a)
运行结果
函数内是局部变量 : 1
函数外是全局变量 : 5
global关键字
如果想要在函数内部用模块定义的变量的话,就需要用到global关键字
a = 5
def hello():
global a
# 声明告诉执行引擎用的是全局变量a
a = 1
print('In test func: a = %d' % a)
hello()
print('Global a = %d' % a)
In test func: a = 1
Global a = 1
可以看到函数里成功修改了全局变量a