cc1989summer 发表于 2024-8-14 22:27

《人工智能实践教程——从Python入门到机器学习》阅读分享二:面向对象及高级编程

<div class='showpostmsg'><p><span style="font-size:18px;">《人工智能实践教程&mdash;&mdash;从Python入门到机器学习》的第二章、第三章,主要介绍面向对象及高级编程</span></p>

<p><span style="font-size:18px;">这部分来到Python编程语言的核心部分。</span></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<div style="text-align: center;"><span style="font-size:18px;"></span></div>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>第二章,重点讲解面向对象编程与面向过程的特点及适用性</strong></span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">结合我自己的理解,总结如下:</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">用洗衣机洗衣服,来看一下两者的差别。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>面向过程:(绝大多数人最早学习以及接触到的方法,单片机开发也通常用的方法)</strong></span></p>

<p><span style="font-size:18px;">以过程(动作、步序)为核心。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">放衣服(方法)--&gt;加洗衣粉(方法)--&gt; 加水(方法)--&gt; 漂洗(方法)--&gt; 清洗(方法)--&gt; 甩干(方法)</span></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<pre>
<code># 面向过程的例子
def add(x, y):
    return x + y

result = add(3, 5)
print(result)</code></pre>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>面向对象:</strong></span></p>

<p><span style="font-size:18px;">以对象(人、物等)为核心。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">归纳出两个对象 &rdquo;人&ldquo; 和 &rdquo;洗衣机&ldquo;</span></p>

<p><span style="font-size:18px;">&rdquo;人&ldquo; 加入属性和方法:放衣服(方法)、加洗衣粉(方法)、加水(方法)</span></p>

<p><span style="font-size:18px;">&rdquo;洗衣机&ldquo; 加入属性和方法:漂洗(方法)、清洗(方法)、甩干(方法)</span></p>

<p><span style="font-size:18px;">然后执行:</span></p>

<p><span style="font-size:18px;">人.放衣服(方法)-&gt; 人.加洗衣粉(方法)-&gt; 人.加水(方法)-&gt; 洗衣机.漂洗(方法)-&gt; 洗衣机.清洗(方法)-&gt; 洗衣机.甩干(方法)</span></p>

<p>&nbsp;</p>

<pre>
<code># 面向对象的例子
class Calculator:
    def add(self, x, y):
      return x + y

calc = Calculator()
result = calc.add(3, 5)
print(result)</code></pre>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>面向对象和面向过程的优缺点对比</strong><br />
面向过程:</span></p>

<p><span style="font-size:18px;">优点:效率高,因为不需要实例化对象。</span></p>

<p><span style="font-size:18px;">缺点:耦合度高,扩展性差,不易维护(例如:每个步骤都要有,不然就不行)</span></p>

<p><span style="font-size:18px;">面向对象:</span></p>

<p><span style="font-size:18px;">优点:耦合低(易复用),扩展性强,易维护,由于面向对象有封装、继承、多态性的特点,可以设计出低耦合的系统,使系统更加灵活、更加易于维护。</span></p>

<p><span style="font-size:18px;">缺点:效率比面向过程低。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">一般来说,小型程序用面向过程足矣,而大型程序,考虑到复杂性、复用性,一般用面向对象编程。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">对于C语言来说,是完全面向过程的。<br />
对于C++语言来说,是一半面向过程,一半是面向对象。(C++是半面向对象的)<br />
对于Java语言来说,是完全面向对象的。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">Python 是一种多范式的编程语言,它<strong>既支持面向过程编程,也支持面向对象编程。</strong>这意味着你可以使用面向过程的方式编写程序,也可以使用面向对象的方式。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">接下来重点讲解了Python面向对象的特征:类、属性、封装、继承等。</span></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>第三章,重点讲解Python高级编程,重点讲解Python闭包和装饰器、迭代等</strong></span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">闭包的定义:</span></p>

<p><span style="font-size:18px;">在Python中,闭包(Closure)是指一种函数,它可以访问在其定义范围内的变量,并把该函数作为返回值返回。闭包允许你在一个函数中嵌套另一个函数,并且在内部函数中引用外部函数的变量。在Python中,如果一个函数定义在另一个函数内部,而内部函数使用了外部函数的变量,则称这个内部函数为闭包。闭包是Python中一种强大的编程技巧,它可以让函数保留状态,并在多次调用之间共享状态。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>闭包的概念听起来一头雾水。</strong></span></p>

<p><span style="font-size:18px;">不如举个例子来理解吧:</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">我们需要一直记录自己的学习时间,以分钟为单位。就好比我学习了 2 分钟,就返回 2 ,然后隔了一阵子,我又学习了 10 分钟,那么就返回 12 ,像这样把学习时间一直累加下去。</span></p>

<p><span style="font-size:18px;">面对这个需求,我们一般都会创建一个全局变量来记录时间,然后用一个方法来新增每次的学习时间,通常都会写成下面这个形式:</span></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<pre>
<code>time = 0

def insert_time(min):
    time = time + min
    returntime

print(insert_time(2))
print(insert_time(10))</code></pre>

<p>&nbsp;</p>

<p><span style="font-size:18px;">认真想一下,会不会有什么问题呢?</span></p>

<p><span style="font-size:18px;">其实,这个在 Python 里面是会报错的。会报如下错误:UnboundLocalError: local variable &#39;time&#39; referenced before assignment</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">那是因为,在 Python 中,如果一个函数使用了和全局变量相同的名字且改变了该变量的值,那么该变量就会变成局部变量,那么就会造成在函数中我们没有进行定义就引用了,所以会报该错误。</span></p>

<p><span style="font-size:18px;">如果确实要引用全局变量,并在函数中对它进行修改,该怎么做呢?</span></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">我们可以使用 global&nbsp;关键字,具体修改如下:</span></p>

<p>&nbsp;</p>

<pre>
<code>time = 0


def insert_time(min):
    globaltime
    time = time + min
    returntime

print(insert_time(2))
print(insert_time(10))</code></pre>

<p><span style="font-size:18px;">输出结果如下:</span></p>

<pre data-index="3">
<code>2
12</code></pre>

<p><span style="font-size:18px;">可是啊,这里使用了全局变量,我们在开发中能尽量避免使用全局变量的就尽量避免使用。因为不同模块,不同函数都可以自由的访问全局变量,可能会造成全局变量的不可预知性。比如程序员甲修改了全局变量 time 的值,然后程序员乙同时也对 time 进行了修改,如果其中有错误,这种错误是很难发现和更正的。</span></p>

<p><span style="font-size:18px;">全局变量降低了函数或模块之间的通用性,不同的函数或模块都要依赖于全局变量。同样,全局变量降低了代码的可读性,阅读者可能并不知道调用的某个变量是全局变量。</span></p>

<p><span style="font-size:18px;">那有没有更好的方法呢?</span></p>

<p><span style="font-size:18px;">这时候我们使用闭包来解决一下,先直接看代码:</span></p>

<p>&nbsp;</p>

<pre>
<code>time = 0


def study_time(time):
    def insert_time(min):
      nonlocaltime
      time = time + min
      return time

    return insert_time


f = study_time(time)
print(f(2))
print(time)
print(f(10))
print(time)
</code></pre>

<p><br />
<span style="font-size:18px;">输出结果如下:</span></p>

<p><span style="font-size:18px;">2<br />
0<br />
12<br />
0<br />
1<br />
2<br />
3<br />
4<br />
这里最直接的表现就是全局变量 time 至此至终都没有修改过,这里还是用了 nonlocal 关键字,表示在函数或其他作用域中使用外层(非全局)变量。那么上面那段代码具体的运行流程是怎样的。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>这种内部函数的局部作用域中可以访问外部函数局部作用域中变量的行为,我们称为: 闭包。更加直接的表达方式就是,当某个函数被当成对象返回时,夹带了外部变量,就形成了一个闭包。</strong></span></p>

<p><span style="font-size:18px;"><strong>闭包避免了使用全局变量,此外,闭包允许将函数与其所操作的某些数据(环境)关连起来。而且使用闭包,可以使代码变得更加的优雅。而且下一篇讲到的装饰器,也是基于闭包实现的。</strong></span></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;"><strong>装饰器</strong>本质上是一个函数,它可以接收一个函数作为参数并返回一个新的函数。这个新函数是对原函数的一种包装或增强,可以在不改变原函数代码的前提下,增加额外的功能。</span></p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">通俗点说:</span></p>

<p><span style="font-size:18px;">装饰器就是类似于女孩子的发卡。你喜欢的一个女孩子,她可以有很多个发卡,而当她戴上不同的发卡,她的头顶上就是装饰了不同的发卡。但是你喜欢的女孩子还是你喜欢的女孩子。如果还觉得不理解的话,装饰器就是咱们的手机壳,你尽管套上了手机壳,但并不影响你的手机功能,可你的手机还是该可以给你玩,该打电话打电话,该玩游戏玩游戏,而你的手机就变成了带手机壳的手机。</span></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">举个例子:</span></p>

<pre>
<code>def decorator(func):
    def wrapper(*args, **kwargs):
      # 在这里添加额外的功能
      print("Before calling the function")
      result = func(*args, **kwargs)
      print("After calling the function")
      return result
    return wrapper

@decorator
def my_function():
    print("Hello, this is my function.")

# 调用my_function时,实际上调用的是wrapper函数
my_function()

</code></pre>

<p>&nbsp;</p>

<p><span style="font-size:18px;">简单的理解:decorator函数对wrapper进行了装饰,增加了新的功能。</span></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><span style="font-size:18px;">今天的学习分享就到这里。</span></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

Jacktang 发表于 2024-8-15 07:29

<p>decorator函数对wrapper进行了装饰,增加了新的功能。</p>

<p>这个理解到位</p>

cc1989summer 发表于 2024-8-17 19:52

Jacktang 发表于 2024-8-15 07:29
decorator函数对wrapper进行了装饰,增加了新的功能。

这个理解到位

<p><img height="50" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/wanwan33.gif" width="58" /></p>

风尘流沙 发表于 2024-10-28 10:22

<p>谢谢楼主的分享<img height="50" src="https://bbs.eeworld.com.cn/static/editor/plugins/hkemoji/sticker/facebook/wanwan33.gif" width="58" />,我去找书看一下。</p>

cc1989summer 发表于 2024-10-28 17:30

风尘流沙 发表于 2024-10-28 10:22
谢谢楼主的分享,我去找书看一下。

<p>一起学习进步{:1_144:}</p>
页: [1]
查看完整版本: 《人工智能实践教程——从Python入门到机器学习》阅读分享二:面向对象及高级编程