00:00
说完了函数的B包,接下来我们来再说一下我们这个高阶函数啊,也是一个高阶函数的一个应用啊,我们在这单独写一下,叫做一个什么呢?诶叫做一个装饰器啊,装饰器是干嘛的啊,我们直接来演示啊,直接来通过代码来演示这个东西啊,那在这里我来新创建一个文件啊,在我们这个这个文件夹下。呃,直接来一个啊,保存一下,我们这儿来一个这个一零,我们叫一个什么呢?叫一个装饰器,呃,装饰器这里边我们先不说它是什么意思啊,我们先来举个例子啊,我们在这来干嘛呢?哎,我们来创建这个几个函数啊,创建几个这个函数,呃,直接写了啊,诶DEF范我们来一个这个,呃,来一个这个什么呀,先来一个随便写一个吧,FN1啊FN1这函数我们简单定义一下啊,我们来写一个这是什么呢?哎,我是这个FN1啊或者这样吧,咱们定点有意义的啊,有意义的这个呢,我们来一个I啊,叫一个求和的一个函数,或者叫sum都行啊,Sum都行,两个参数,一个是A,然后呢,这一个是B,简单一点,我这就直接干嘛呢?哎,直接re return一个A加B求和的对吧,然后再来一个啊,我们来定义一个DeFine,我们来一个这个,诶玛,Ullull也是来一个。
01:26
A来一个这个B,这个是什么呢?这个是求两个数的一个,哎,两个数的乘积的啊,也是返回一个A乘以一个,哎,A乘以一个这个B啊这么一个效果好,那现在我们有了这么两个函数,一个是I的啊,我们来这写个给它补充个这个文档字符串。这是干嘛的呢?哎,这是求。哎,任意哎两个。哎,竖的一个这个和下边这个呢,这个我们来写一下,这个是我们叫做一个球。
02:03
哎,任意两个数的一个积啊,任意两个数的一个积。一啊好,那现在啊,我来调用一下,呃,直接来一个R啊,结果就叫二吧,等于一个I的,我们来一个这来一个这个123逗号,一个456直接保存,我们这来一个print一下这个R,这一保存一执行,是不是给我们算出一个579啊哎579,然后呢,我这再来一个,来一个什么呢?哎来一个这个把改成我们这个mui,我们这个mart,我们这一执行是不是给我算出一个乘积来呀,哎算123和五就有一个乘积,那这个东西现在是非常非常的简单的对吧,就是一个求和的函数,还有一个是求积的函数啊就这么两个函数,那接下来我们说一个什么问题呢?哎,我现在有这样一个需求啊,什么需求呢?哎,我希望,哎希望什么呢?哎,希望我们这个函数可以什么呢?哎,可以在计算前,哎计算前打印一个,哎在什么呢?诶在这个计算前。
03:09
哎,打印什么呢?哎打印我们叫做一个什么呀?哎叫做一个。开始计算啊开始计算,然后什么呢?诶计算我们这个结束以后干嘛呢?诶计算结束后打印什么呢?诶打印一个这个,诶计算。完毕啊,完毕什么意思啊,我们在这儿是不是要掉了一个这个I的这个函数啊,哎,我希望什么呢?哎,它在干嘛呀?哎,你刚调的时候是不是要计那个A加B的结果呀?哎,在计算前你先给我打印一个啊开始计算了,结果出来以后你告诉我干嘛呀,结果计算完毕了啊结果计算完毕了,所以这个东西我们要改的话,我要实验这个需求怎么办?其实非常简单,在前边呢,我先打印一个,打印什么呢?不认那一个,诶不是担心一个叫什么呢?诶叫计算开始啊,然后一个省略号,然后诶咱们在别在这个文档字符串前面去写它,对吧,我们还是把它写到这个位置。
04:05
计算开始,然后在这我来计算,直接来一个R等于个A加B,那这是不是就计算完了,哎,这我们来写一个print,来一个这个计算结束啊,计算结束然后呢,我这直接就返回啊,哎,返回我们的一个二,是不是最终把结果返回啊,这样我们一保存,这时候再掉来一个二等于个I的,我们来一个123逗号一个456,在这我们直接普加二,这时候我们再掉,它就告诉你什么呀,计算开始,计算结束,然后在这里边是不是给你打一个结果呀,哎,这是我们的一个,哎希望,哎希望可以达到这么一个效果啊,计算前打印一个计算开始,然后打印个计算结束,最后是不是在输出结果呀,哎,输出结果,但是这个你是不是也可以这么改啊,哎,也可以这么改啊,我先给它改回来啊,我先给它改回来,那现在啊,我把这两个给它统一一下啊,把格式给统一下,都写成这种形式。多写这种形式啊。那现在这个东西其实看起来这个需求非常简单对吧,你其实就是在加之前或者乘之前打印一个什么呀,计算开始,加之后或者乘之后打一个计算结束,这功能是不是就完事了,其实看起来是非常非常的简单的啊,非常非常简单的,那这里。
05:20
有一个什么问题呢?有个什么问题呢?第一个问题,第一个问题现在我们说了,我们要想实现这个功能,我们要说你就想一个函数里实现是不是非常简单呀,但是一旦你有多个函数了,哎多个函数了,那你是不是要去每一个函数都要修改啊,哎,每一个函数都要修改,所以这里边我们来说一下,如果我们可以什么呢?哎,我们可以直接通过修改函数中的这个什么呀,哎,代码哎来完成这个什么呀,哎来完成这个需求啊,来完成这个需求,但是它会什么呢?诶会产生以下一些问题。
06:02
一些问题对吧,它不是一两个,哎不是不是一个问题对吧?哎一些问题,那什么问题啊,第一个第一个是什么?哎,第一个如果要修改的函数过多,如果要修改函数过多,那现在你改一个还搞不改,你要十个呢,有100个呢,哎如果修改函数过多,修改起来会什么呀?诶会比较麻烦啊会比较麻烦,这是我们面临的第一个问题对吧?改起来比较麻烦,第二一个并且改起来麻烦,我们说了改都不是最麻烦的,最麻烦是什么呀?是维护,哎并且干嘛呀?哎它不方便我们后期的一个维护,什么叫维护,那我现在比如说我现在加法这个,我想打印一个计算开始,然后计算结束,对吧?乘法我也想打印计算开始,计算结束,那过两天可能我加法我不想打印了,我只有这个乘法型打印,加法不想打印了,那这个时候我是把加法这给删了呀,哎,那再过两天可能我别的又有几个不想打印的了,我是不是要删呀,那过两天我不想打印,计算开始,计算结束,我想打印什么呀。
07:03
哎,计算这个begin,我先打个end,那这个时候我是要一个一个去改,维护起来会非常非常的麻烦,非常非常不方便呀,哎,所以这是我们的第二个问题,它不方便我们的后期维护啊,不方便我们后期的这个维护,那除了这两点还有什么问题呢?诶还有什么问题呢?哎,那注意哎,并且咱们现在想想,现在这个函数是我自己定义的,对吧?无论是这个I的也好,还是这个mart也好,这个两个函数都是我自己定义的,那既然是我自己定义的,我想怎么改就怎么改,对吧?但是假如说这个函数它不是我定义的啊,它不是我定义的,它是谁定义呢?它是。别人定义的,哎,我是拿过来直接就去使用的,哎我拿过来就用,而不是我定义的,那这个时候会干嘛。我是不是改不了啊,因为压根函数就不是我定义的,你要想改,你是不是也改不了,哎,也改不了,所以这里边我们注意了,我们开发的时候,我们有一个原则叫做一个OCP。
08:12
哎,O c po叫什么呢?O叫做openc呢?叫做一个close啊,Closep呢叫做一个原则,OCP叫做开闭原则啊,开闭原则我们叫什么呢?哎,并且。哎,这样做会什么呢?哎,会违反我们的开闭原则。什么叫开闭原则啊,我们这里边简单说一下啊,开闭原则我们叫做一个OCP啊OCP什么叫开闭原则,开就是开放,闭就是关闭啊关闭,那我们对什么开放,哎,我们程序开发时。哎,程序的设计我们要干嘛呀?哎,我们要求什么呢?要求对我们程序的什么呀,诶叫做扩展,哎要求什么呀,要求我们开放对程序的这个扩展,而什么呢?而要什么呀?哎关闭我们这个对我们这个程序的一个修改。
09:07
什么意思?哎,就是说我给你这么一个函数,给你这么一个东西,你拿过去用,哎,你觉得这功能不满足,你可以干嘛?你可以对它进行扩展,你说我要想对它干嘛呀,增强一下功能,我想对它升级可以,但是你说我想去直接去改你这个程序,比如说你给我提供了一个hello,这函数,这hello不是我的,是别人给我提供的,那现在这个函数你可以用,对吧,给你了你就可以去用,那这时候你觉得不满足你的需求,你也可以干嘛呀,你也可以对这个函数进行升级,进行扩展,但是你说了我想直接去修改你这个函数行不行?哎,注意这个是绝对不行的,这就是我们说开辟原则,对什么开对扩展开放,而什么呢?对我们这个什么呀,修改要关闭,也就是说一般情况下,我们不是一般情况下,所有情况下我们都是不能去直接修改我们的源代码的,就是诶当然你自己写,你可以改别人给你的,一般我们都不要去改,因为改了以后别人是不是有可能在别。
10:08
别的地方去用啊,你改了人家不知道,人家拿过去用了,那是不是容易出现问题啊,哎,所以我们有一个叫做OCP原则,叫做开闭原则,对扩展开放,但是对这个什么呀,修改关闭啊,那这个时候有同学听到这儿就会有疑问了,对扩展开放,对这个修改关闭,那我要对它进行扩展,那实际上不就是修改它吗?诶那这块就带来一个问题,我能不能在不修改这个函数的情况下。对这个函数进行扩展。不修改函数,但是我还要对它进行扩展,对吧?那如果我能满足这个要求,那我是不是这三个问题是不是全都解决了,哎全都解决了,所以这里边我们来说需求了,我先把这住掉啊,我们什么需求啊,我们希望,哎,我们希望在不。
11:05
修改,哎,原函数的这个情况下来干嘛呢?哎,来对我们这个函数进行扩展。不修改原函数,但是你还要对函数进行扩展,那怎么办呢?那怎么办呢?那现在我们拿这两个函数演示起来稍微有点麻烦,我们这样啊,DEF,我们创建一个新的函数FNFN呢,我们这直接就来一个print print来一个什么呢?哎,我是FN,我是FN这个函数,那现在我就希望对它进行扩展,怎么扩展,我希望在这个函数执行前打印一个。函数执行。函数将要执行,在函数执行后,打印一个函数执行完毕,那这个时候我是不是就要对它进行扩展,对吧?那我要怎么扩展?
12:03
你还不能改它,你还要对它进行扩展,是不是很麻烦呀?哎,其实不麻烦,你不能改它,你还要对它进行扩展,那其实说白了就是什么呀,我们只需要做一件事儿,我们其实我们只需要根据我们现有的函数来干嘛呢?诶,来创建一个新的函数啊,那既然你不让我改的,你要对要对它进行扩展,那我不改你现在的干嘛呀?我根据你现有的函数,我创建一个新的函数不就完了对吧?我创建一个新的函数,那其实这道理非常简单,我直接定义一个FN2 FN2我这里边干嘛呀?哎,FN2,那你让我在调用它之前先打一个函数执行了,对吧?那我就得print的一个,Print一个干嘛呢?哎,函数,哎函数开始执行。开始执行,然后再往下,我这再来一个函数什么呀?哎,函数执行结束,函数执行结束,然后呢,在中间我这掉一个FN,哎,在中间我这掉一个FN,那这个时候我们来看效果,这个时候我们来看效果,那怎么你看着啊,我这掉一个FN2,那注意了,我现在去掉FN2,而在FN2中我们是不是掉了FN啊,我掉了FN,那我等于我掉了FN2,是不是就再就等于再掉FN呀,而且这个时候注意了,注意什么,我这里边。
13:31
是不是有两个print的语句啊,等于我在调FN的时候打印了这句话,在调完FN是不是打印这句话呀,那这个时候我再调FN2,看什么效果,这一执行来看,函数执开始执行,我是FN函数,函数执行结束,那这样我们是不是就达到了对FN函数一个扩展呀,那注意啊,函数的确扩展了,FN函数的确调用了以后,你只需要就去调FN2,是不是就等于去代替了FN啊,的确是扩展了,那我有没有修改原来函数,哎,没有,原来函数是不是压根儿就没有任何的。
14:05
变化呀,哎,没有任何的变化,那这样我们是不是就完成了,哎完成了啊,就完成了对它的一个扩展啊,完成对它的扩展,哎,但是这里边我们说了,老同学说老师你为什么扩展FN,刚才我们这有这个爱的,有这个有这个这这个Mar,你为什么不对它们进行扩展,哎,那我能不能对它进行扩展,哎其实一样的啊,一样,那比如说我要对这个艾进行扩展,那怎么扩展,我直接DEF,我们来一个new,一个I的,然后括号,我这里边干嘛呀,我们还是先打印一个干嘛呀,函数开始执行了,然后呢,我这打印一个函数执行结束了,是不是一样的呀?哎,中间我只需要掉一个爱的是不是就OK了,但是问题来了啊,你说我光这么写行不行,看着啊,我直接来一个,来一什么呢?来一个这个new,一个这个艾,我直接去调这个艾一保存我们这一执行走一个就完了。
15:02
是不是报错了,告诉你I的丢失了两个必要的参数A和B,哎,没有这个A和B这两个参数,为什么呀?哎,为什么?因为我们刚才所定义的FN,它是一个没有参数的函数,而我们这个I的这是不是需要两个参数啊,哎,两个参数,而你在这个new ID里去调的时候,有没有传这两个参数,哎没有传,没有传这时候就报错了,哎就报错了,那怎么办?那怎么办?哎你可以这样,你在这个new ID里边,你去定义两个参数,比如说你在这定义一个A,定义一个B,然后干嘛呢?把A和B作为参数传到这个ad里,那这时候你这再传一个123,这来一个456,这一保存走一个,诶是不是就也行了,哎就OK了,但是这是没有给我显示结果呀,哎,没有显示结果,但是我们是不是,诶,那么这样我是不是需要让它显示结果呀,为什么没有显示结果,因为我们压根是不是就没有去输出那个结果呀,但是问题来了,这个结果它在哪了呀?
16:02
这个结果在哪儿?现在注意了,我们说了结果我们肯定得需要通过返回值去接收,那我在这儿去接收一个返回值,注意这我能不能获取到结果,哎,你注意了,我们的I的这个函数的确是返回了一个A加B,但是这是它的返回值吧,我现在这接收返回值接收的是谁的?哎是这个new a的,这有没有返回结果,哎,没有返回结果,所以这个R有没有值,哎注意我这一打印R是不是是那呀,哎是那那这可怎么办呀?哎呀你这这这这这是是的确是提升了对吧?我听通过new爱的来代替爱的,但是现在我是不是看不到结果呀?哎,看不到结果那要怎么办啊?那要怎么办?那怎么办?我们想一下,哎,那既然你的结果在这儿呢,那我直接来一个什么呀,来一个R等于X,我在里边用一个变量去接收,在函数执行完毕以后,我特一个二,我把这个结果返回是不是就OK了,哎,我把这个结果给你返回回去,这个时候我们再一执行啊,再一执行,我们来看效果,走一个是不是就有结果了,哎,有结果了啊,再来一个咱们或者这样的,我们来一个什么呀,计算开始。
17:20
计算开始,这来什么呢?来一个计算结束,这一保存啊,然后在这来看一执行是579啊哎579诶然后呢,我们再来换一个换一个换一数吧,三个一加上三个二这一保存一执行。是不是算出来了,哎,算出来了,那这样我们通过这种方式是不是就对我们这个I的函数进行了扩展呀?哎,进行扩展,当然这个版本还不是我们的最终版本,但是它已经达到了我们的要求,也就是说我没有违反OCP原则,也就是说我的确对你的函数进行功能扩展了,怎么扩展了,你开始没有办法打印计算开始和计算结束吧,当我扩展以后,是不是能打印计算开始,计算结束了,并且你原来的功能有没有影响,哎,你的加法功能没有产生任何影响,的确对它进行了扩展,而且有没有修改源代码,诶,I的的代码我是不是一点都没变呀?哎,一点都没变,那我通过这种方式对爱的进行了扩展,但是他现在有什么问题,有什么问题,哎,很严重的一个问题,什么问题?那我现在这是对I的进行扩展,那我要想对这个mart行扩展呢?那我是不是还得定一个new Mar啊,我要想对别的函数呢,我是不是还得定一个新的函数啊,我要想。
18:35
对十个函数进行扩展,那我要定义十个新函数,我要想对100个函数进行扩展,我是不是要定义100个新函数,那我每一个都定义一个的,都一个一个定义,是不是很麻烦呀?那我们就想了,我能不能把这种方式变成一个通用的,我既可以对I的进行扩展,也可以对马进行扩展,也可以对其他的函数进行扩展,我能不能把它变成一个通用啊,那这个问题就需要大家去思考一下啊,思考一下那其实也非常非常的简单,诶,其实就是一个步骤啊,就是一个步骤把这个问题好好的去思考一下,然后先把我刚才所的事儿自己尝试去写一下,再去思考这些问题啊,我们来先停一下。
我来说两句