Python 函数参数的填坑之路

背景

最近在看廖雪峰老师的python3教程之函数的参数
受益匪浅,但是在实践的过程中,发现了一些不解之谜

两个错误

import _thread
import time
def func1(x):
    while x:
        print(x)
        x = x -1
_thread.start_new_thread(function=func1,args=(5,),kwargs=None)
time.sleep(6)

再看python3中start_new_thread()函数的声明

def start_new_thread(function, args, kwargs=None):

按照我们的理论,我们开启多线程的那句代码是完全没有问题的,可是事实上它报错:

TypeError: start_new_thread() takes no keyword arguments

难道我们的理论有问题?带着这个疑问,我又遇到一个问题:

import threading
def func1(x):
    while x:
        print(x)
        x = x -1
threading.Thread(func1,(5,)).start()

再看python3中Thread类构造()函数的声明

def __init__(self, group=None, target=None, name=None,
             args=(), kwargs=None, *, daemon=None):

它居然又报错?

AssertionError: group argument must be None for now

探讨过程

(以下过程针对第二个错误,第一个错误道理类似)
带着疑问,我看了Thread类的构造函数

def __init__(self, group=None, target=None, name=None,
     args=(), kwargs=None, *, daemon=None):
      """This constructor should always be called with keyword arguments. Arguments are:

       *group* should be None; reserved for future extension when a ThreadGroup
        class is implemented.

        *target* is the callable object to be invoked by the run()
        method. Defaults to None, meaning nothing is called.
        。。。略

        assert group is None, "group argument must be None for now"
        。。。略

我们看到,第三行说明,本函数只接受关键字实参调用,所以我们之前的代码改成

import threading
def func1(x):
    while x:
        print(x)
        x = x -1
threading.Thread(target=func1,args=(5,)).start()

就能顺利开启子线程了,那么它是如何实现只能接受关键字参数的呢?
我们看到Thread类的构造函数定义中有一句这样的断言

assert group is None, "group argument must be None for now"

意思是,如果参数group为空,通过;如果非空,报错,并给出reasongroup argument must be None for now,如果我们按照之前的位置参数调用的话,由于group是第一个参数,一下在就被赋值,非空,抛出异常,这符合我们之前的实践。同时,我在网上搜集了许多资料,诸如修饰器之类的也能使函数只接受关键字参数 。

错误一探讨过程道理类似,在此不再赘述。

验证及结论

编码

class MyThread:

    def __init__(self, group=None, target=None, name=None,
    args=(), kwargs=None, *, daemon=None):
        print('Thread sucess')

    def start_new_thread(function, args, kwargs=None):
    print('_thread sucess')

MyThread()
MyThread.start_new_thread(args=2,kwargs=3,function=1)

输出如下:

Thread sucess
_thread sucess

显而易见,我们之前所学的理论是正确的,只不过在具体的编码中,我们通过编码修改
理论,使之看上去似乎和之前的理论相矛盾,千万不要被蒙蔽了。

本文标题:Python 函数参数的填坑之路

文章作者:月小水长

发布时间:2018年11月22日 - 20:11

最后更新:2019年04月09日 - 09:04

原始链接:https://inspurer.github.io/2018/11/22/python函数参数的填坑之路/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

您的赞助将鼓励我继续创作!
-------------本文结束感谢阅读-------------