[Exdepressionn.ERROR]2参数传递到了一个函数,该函数应为1?

VIP专享文档是百度文库认证用户/机構上传的专业性文档文库VIP用户或购买VIP专享文档下载特权礼包的其他会员用户可用VIP专享文档下载特权免费下载VIP专享文档。只要带有以下“VIP專享文档”标识的文档便是该类文档

VIP免费文档是特定的一类共享文档,会员用户可以免费随意获取非会员用户需要消耗下载券/积分获取。只要带有以下“VIP免费文档”标识的文档便是该类文档

VIP专享8折文档是特定的一类付费文档,会员用户可以通过设定价的8折获取非会員用户需要原价获取。只要带有以下“VIP专享8折优惠”标识的文档便是该类文档

付费文档是百度文库认证用户/机构上传的专业性文档,需偠文库用户支付人民币获取具体价格由上传人自由设定。只要带有以下“付费文档”标识的文档便是该类文档

共享文档是百度文库用戶免费上传的可与其他用户免费共享的文档,具体共享方式由上传人自由设定只要带有以下“共享文档”标识的文档便是该类文档。

}

课前补充个新的概念:为什么要萣义函数

  为了使用。函数即变量变量怎么定义的x=1调用函数分为两部分:先找到当前你要调用的函数有没有那个名字。有了这个函數名字加括号,才是执行这个函数里面的代码定义函数就相当于在定义了一个变量,函数名就是变量名函数值就是函数体里面的代碼。如果没有事先定义函数而直接引用,就相当于在引用一个不存在的变量所以函数的使用一定要遵循先定义后使用的原则。

  函數对象指的是函数可以当做数据去传递!(什么叫数据呢x=1相当于定义了一个数据,那x与什么特性函数就应该有什么特性!特性如下:)

闭包函数的特点:拿到函数,在任何位置执行要找他里面引用的值优先从哪里找?优先从自己包的那层作用域开始找也就相当于这個函数自带的一种状态。

辅助验证闭包函数的概念可以看出他外面包的内容:

闭包函数的核心:内部函数,包含对外部作用域的引用return紦这个函数返回来。

  装饰器指的是修饰别人的工具修饰指的是添加功能,工具指的是函数装饰器本身可以是任何可调用(名字加括号可以执行的,这就是可调用的)对象被装饰的对象也可以是任意可调用对象。

  开放封闭原则:对修改是封闭的对扩展是开放嘚,(比如你在公司写了一款游戏这个游戏最终要上线,上线完了之后这些代码就一直不动了么会有改的需求,那么问题来了!假如伱写的代码是一个一个的函数让你进行功能的修改,那么你打算怎样去做去改源代码的话风险特别大,因为你一个函数可能很多地方嘟在用你把定义的源代码给改掉了,影响的可能不是一个点可能影响到好多其他地方,牵一发而动全身如果你改对了,那就没问题一旦你改错了呢?就会导致一系列的连锁反应可能这个软件都会垮掉,所以已经上线的程序,源代码要尽量避免修改但是,难道僦不改了么对修改源代码这种操作应该封闭起来,但是对于扩展功能你还不得不做你的代码一定要为后期的这种扩展留下可能性,而苴还不能动源代码这就用到了装饰器的功能。)装饰器就是为了在不修改被装饰对象的源代码以及调用方式的前提下为其添加新功能。

3 #模拟统计一个函数执行了多长时间 10 #现在就统计上面的按个函数执行用了多长时间,如果用下面这种写法就违反了不可修改源代码的规则 20 #偠保证源代码不能动,调用方式也不能动

上面例子也可以用闭包函数实现:

不能每次都调用也可以使用装饰器完成:

我们来分析一下装飾器的流程

 1 #代码是从上而下解释执行
 4 import time#1、只是定义一个名字而已,没有任何意义
 5 def timmer(func):#2、这就是定义了一个名字没有意义,把他折叠合上
 6 def wrapper():#4、首先這定义的是一个函数把他折叠上,他就是一个名字而已
13 @timmer #3、他会把他正下方的这个函数名当成是参数传进来,而且这种方式是固定的这就昰装饰器的语法,这个函数的返回值在重新给index打开折叠的index函数,看看他都执行了什么
14 def index():#6继续往下走到这部,这个函数就是一个定义没意义,折叠上
 

流程分析完了我们想想这有什么问题?见如下代码为什么返回的是null而不是1?倒数第二行表明了其原因!现阶段你只要學会了这个流程,写装饰器怎么写把闭包函数的格式套过来。装饰器就是闭包函数的一种实现方式

那该怎样修正呢?如下修正返回結果就是1了

5 res=func()#(2)这里调的就是index(),我们已经把这个返回值func()暂存下来了res等所有功能加载完之后,我们在把最原始函数的返回值当做wrapper函数的返回值茬返回就可以

在考虑下,如果index换成有参函数呢

上面函数报错,wrapper函数需要0个参数但是确给了一个!原因是foo('egon')就相当于调用了wrapper,并传了一個参数进去那这种情况如何解决呢?加一个参数就可以了如下代码:

如果将如上的代码注释掉的内容

发现将注释放开之后,上面的wrapper又鈈需要参数了这就是用到了可变长的概念,可能有也可能没有长度不固定。那怎么解决这个问题!如下利用*args和**kwargs

接下来写一个装饰器實现一个认证功能。现在定义一堆函数在这些函数真实的功能执行之前,加上一段认证功能只有认证通过了了,才能去执行他的一个嫃实的功能

比如对如下函数进行认证

登录成功进行打印,否则提示登录错误代码如下:

上面的代码存在一个问题:您输入完登录用户洺和密码之后已经登录成功,可以点主页了为什么还是让输入用户名和密码再次进行认证呢?用session保存一下session就是一堆变量的定义,没什麼特别之处登录成功就要把登录的状态记录下来,下次再需要登录的时候直接从认证结果里面去取看有没有登录如果已经登录了就直接认证通过,就不用再认证了现在来模拟一下怎么实现呢?

2 #定义一个全局变量一开始没有用户登录,所以为None,默认的状态为未登录的状態

想这样的一个问题你公司的认证,来源就是一个数据库么也有可能从ldap、文件里面取,各种各样的认证源你得给这个认证源提供接ロ,让别人能够选择通过哪种方式来认证这就涉及到有参装饰器了。之前我们使用的是无参装饰器没有传任何参数,直接写了函数名芓对于有参装饰器怎么玩的呢?

3 #认证来源为文件这是闭包函数,使driver这个参数被auth2这个函数使用

叠加多个装饰器的使用情况:

,他修饰的是他囸下方对着的函数,如果在@auth('file')上面再加一个装饰器@timmer的话他修饰的是谁呢?@timmer也是修饰他正下方的函数他正下方的函数就是@auth('file'),这个auth拿到的结果昰被修改过的index。先执行的装饰器是最上面的@timmer,在执行下面的@auth('file') .这个装饰器的执行顺序对功能调用有没有影响是有影响的,@timmer放在auth('file')上证明你统計的是auth('file')的时间,放在@auth('file')下说明你统计的是index函数的时间。 auth()是为了给index加上认证功能如下代码:

为何时间比8s还长呢?因为中途有控制台输入的過程那如何只统计index函数的时间呢?只需要把@timmer装饰器放在@auth('file')下即可

迭代的概念:重复的过程称为迭代,每次重复一次迭代并且每次迭代嘚结果是下一次迭代的初始值。如下代码只是重复不叫迭代!

下面的内容才是迭代:  

上面为迭代列表,那元组可以进行迭代么

 以上迭玳的例子都是有下标的,那没有下标的呢比如字典,集合为什么要有迭代器:对于没有索引的数据类型,必须提供一种不依赖索引的迭代方式
研究迭代器必须明白这样的概念,可迭代的对象:Python会对一些数据类型内置一些方法内置__iter__方法的,都是可迭代的对象:[1,2].__iter__()#列表'hello'.__iter__()#芓符串(1,2).__iter__()#元组{'a':1,'b':2}.__iter__()#字典{1,2,3}.__iter__()#集合f = open('a.txt''w')#文件
f.__iter__()
只要数据类型下面有__iter__()这种方法的,这个数据类型就被称为可迭代的对象执行__iter__()方法得到的结果就是迭代器(对潒),迭代器对象有__next_方法执行如下:

迭代器有什么特性呢?迭代器没有索引要想取迭代器里面的值,该怎么取呢执行 i._next_()。如下代码不依赖于索引把元素取出来

如果是字典呢?把里面的值一个一个取出来怎么操作?

现在想要把字典里面的全部的值都拿出来怎么操作?以上例子对于字典、文件、集合都可以

补充:统计一个数据的长度怎么统计?

以上概念要是懂了我们看下面的代码:

2 #把这个集合变成迭代器怎么操作呢

如何判断一个对象是可迭代的对象,还是迭代器对象

以上的对象是可迭代的,但是他们是迭代器么用如下代码实現:

如上:列表、字符串、元组、集合、字典都是可迭代的对象。但是只有文件是迭代器对象因为他有__next__方法。但是如图字符串执行了__iter__方法,那么他的结果就是迭代器对象可迭代对象只有__iter__方法,执行该方法得到的是迭代器对象而迭代器对象不仅有__iter__方法,还有__next__方法只鈈过对于迭代器来说这个__iter__没有意义,因为执行完返回的仍然是他本身但是对于for循环就有意义了,他为的就是符合for循环的基本的工作原理

 如下代码,for循环的使用(复习以前学过的):

 

思考下面代码为何for循环会把key拿出来?

 

因为for循环遵循的就是迭代器协议他会执行in 后面的對象的__iter__方法(注意:in后面的对象一定是可迭代的对象。)把他变成一个迭代器对象,然后在next一次for循环就相当于next一次。并且帮你做try的事凊帮你捕捉异常,他就相当于如下代码:

 

可迭代对象一定是迭代器么(不一定)但是迭代器一定是可迭代对象!所以从for级别,无法判斷他是一个可迭代对象还是一个迭代器对象所以,只要后面有对象for都执行他的__iter__方法,如果他只是可迭代的对象那我执行__iter__方法,他就昰一个迭代器如果in后面跟着的是迭代器,那我执行__iter__方法得到的是他本身   

迭代器的优劣:
优点:1、提供了一种不依赖于下标的迭代方式 2、就迭代器本身来说,更节省内存
 1 解释:为什么说迭代器更节省内存呢
 5 i = iter(l)#这样就不会造成所有值都同时在内存里面,next一次取一个值
 9 将文件中内容全部放在内存中,全部展示浪费内存
13 如果是如下写法,一行一行读出来就会节省内存:
16 要遍历怎么遍历呢?
20 这种时候同一时間内存只有一行极大的节约了内存。
缺点:1、无法获取迭代器对象的长度直到next完为止
2、不如序列类型取值灵活,是一次性的只能往後取值,不能往前退

生成器指的是生成器函数:只要函数体包含yield关键字该函数就是生成器函数

在举生成器函数例子之前,看一下如下代碼为什么两次执行的结果都是1呢?

return的特性:只要函数执行到一次return函数立马就终止。

上述代码说明了yield直接把函数转成迭代器了执行next就昰触发这个迭代器。取值的时候就可以用print(next(g))

  如下代码为何只返回了first,返回值哪里去了

14 next(g)#触发迭代器g的执行,进而触发函数的执行

因为 next(g)只是觸发函数执行的结果如果执行print(next('g')),才会显示1.是yield返回的结果,只要碰到yield就会暂停执行并且把后面的值返回来!这就是用yield把函数做成了一个迭玳器。

      2、return只能返回一次值函数就终止了。而yield能返回多次值每次返回就会将函数暂停住。下一次next会从上一次暂停的位置往後继续执行

举个例子,用yield把函数做成一个生成器:

通过这个例子想要说明:不管是if循环还是for还是while循环等其他形式只要执行过程中遇到yield,就是暂停住把yield后面的值当做这次next的返回值返回。讲完这个例子给他讲一下应用场景:做运维的时候要知道这样的一个概念:管道 | 管噵是把左边命令的执行结果作为右面命令的输入。最常见的:tail -f a.txt |grep 'pyhton' 如何用生成器实现呢

13 # print(next(t))#得到他的一个值,注意得往a.txt文件里面写入内容保存才可鉯显示结果 17 #下面代码实现过滤

如上代码在过滤的时候也可以使用yield:

13 # print(next(t))#得到他的一个值,注意得往a.txt文件里面写入内容保存才可以显示结果 17 #下面代碼实现过滤

2、all:1)、for循环一个可循环一个可迭代对象,从可迭代对象里面依次取出他的元素进行布尔值的判断,如果所有的布尔值都是true的话最终返回true。2)、 如果可迭代对象为空那么返回true

print(all([1,2,3]))#列表是一个可迭代对象,for循环[1,2,3]然后取出第一个值进行布尔值运算布尔值1得到的值是true,所有值都是true最终得到的是true。all后面也可以放一个生成器在这里

3、any:1)、只要有一个为true那就为true,都为假就为假  2)、如果传的可迭代对象为空则返回false

4、bin:把十进制转成二进制

5、hex:把十进制转成十六进制

6、oct:把十进制转成八进制  

7、bool:所有的数据类型都自带布尔值

9、char:按照ascii码表把数字转成对應的字符

10、ord:按照ascii码表把字符转成相应的汉字

11、工厂函数,比如list是批量产生列表的

12、divmod:一般用来完成分页功能

13、eval:把字符串里面的命令提取出來执行

如何取出下面字符串里面的字典

这个可以用在什么场景呢以前往文件里面写内容都是字符,如下代码文件里面存的是字典形式:

4 #用文件模拟数据库,现在要取出来跟用户进行比对怎么操作呢? 7 print(dic,type(dic))#这里是以字符串形式显示的但是我想用的是字典,怎么操作呢
4 s.add(3)#可變集合就是s可以往里面加东西,加了东西之后可以打印出来

不可变集合为下面代码s都没有add方法:

16、hash:hash是一种算法,通常用来做校验用的:

  1、只要校验的内容一致那么哈希得到的结果永远一样 

       3、只要采用的哈希算法一样,那无论被校验的内容有多长哈希得到的结果长喥一样

17、id:表示对象的身份。跟他对应的有一个叫is运算

print(x is y)#判断x 和y是否一样,根据他们两个身份进行判断

18、pow:传两个值做平方操作传第三个值取模运算

如下返回列表:list和for一样,也遵循迭代器协议

对上面代码编辑如下返回结果一样,[ ]是因为迭代器已经走完一次:

20、round:保留几位小數

 

22、wars:如果没有参数和locals()一样,如果有参数他和__dic__一样效果

#注意:s和l这两个值,就找一一能对应上的任何一个多一个值都不影响
#time的功能有sleep,那么m会不会有呢会有的,只是输入的时候没有提示了
}

----第一个参数是安全属性一般设為null,使用缺省的安全属性当我们想此线程有另外的子进程时,可改变它的属性 
----第二个参数是线程堆栈尺寸,一般设为0表示与此应用嘚堆栈尺寸相同,即主线程与创建的线程一样长度的堆栈并且其长度会根据需要自动变长。 
----第三个参数也是最重要的一个,是一个指姠函数名的指针或者函数名字 
----第四个参数是你需要向线程函数传递的参数,一般是一个指向结构的指针不需传递参数时,则这个参数設为null 
----第五个参数,传入与线程有关的一些标志如果是CREATE_SUSPENDED,则创建一个挂起的线程,即这个线程本身已创建它的堆栈也已创建。但这个线程不会被分配给CPU时间只有当ResumeThread函数被调用后才能执行;当然,也可以调用SuspendThread函数再次挂起线程要是标志为0,那么一旦建立线程线程函数僦被立即调用。一般传为0即可 ----第六个参数是系统分配给这个线程的唯一的ID标志

注意:传给函数的参数,要保证当运行回调函数时候参數不能被销毁。

比如这里参数是局部变量栈

  WaitForMultipleObjects(MAX_THREADS, hThread, TRUE, INFINITE); //这样传给回调函数的参数不用定位static或者new出来的了
屏蔽,那么传递给回调函数的参数就可能已經被销毁调用函数的时候就会出错、除非将传入的参数定义为static 或者其他在调用完所有线程前不被销毁的变量

WaitForSingleObject的返回值能够指明调用线程為什么再次变为可调度状态。如果线程等待的对象变为已通知状态那么返回值是 WAIT_OBJECT_0。如果设置的超时已经到期则返回值是WAIT_TIMEOUT。如果将一个錯误的值(如一个无效句柄)传递给

下面这个函数WaitForMultipleObjects与WaitForSingleObject函数很相似区别在于它允许调用线程同时查看若干个内核对象的已通知状态:

dwCount参数鼡于指明想要让函数查看的内核对象的数量。这个值必须在1与MAXIMUM_WAIT_OBJECTS(在Windows头文件中定义为64)之间

phObjects参数是指向内核对象句柄的数组的指针。

一种方式是让线程进入等待状态直到指定内核对象中的任何一个变为已通知状态。

另一种方式是让线程进入等待状态直到所有指定的内核對象都变为已通知状态。

fWaitAll参数告诉该函数你想要让它使用何种方式。

如果为该参数传递TRUE那么在所有对象变为已通知状态之前,该函数將不允许调用线程运行

dwMilliseconds参数的作用与它在WaitForSingleObject中的作用完全相同。如果在等待的时候规定的时间到了那么该函数无论如何都会返回。

同样通常为该参数传递INFINITE,但是在编写代码时应该小心以避免出现死锁情况。

如果fWaitAll参数传递 TRUE同时所有对象均变为已通知状态,那么返回值昰WAIT_OBJECT_0

如果为fWaitAll传递FALSE,那么一旦任何一个对象变为已 通知状态该函数便返回。

该索引说明哪个对象变 为已通知状态

说明这一情况的一些示唎代码:
 

如果为fWaitAll参数传递 FALSE,WaitForMultipleObjects就从索引0开始向上对句柄数组进行扫描同时已通知的第一个对象终止等待状态。

这可能产生一些 你不希望有嘚结果

例如,通过将3个进程句柄传递给该函数你的线程就会等待3个子进程终止运行。如果数组中索引为0的进程终止运 行WaitForMultipleObjects就会返回。這时该线程就可以做它需要的任何事情然后循环反复,等待另一个进程终止运行

如果该线程传 递相同的3个句柄,该函数立即再次返回WAIT_OBJECT_0除非删除已经收到通知的句柄,否则代码就无法正确地运行

 
}

我要回帖

更多关于 ression 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信