python如何实现的面向对象_机器学习之Python基础(二)--面向对象

介绍python面向对象基础,下面先看下目录:类

面向对象--继承

面向对象--多态

面向对象--封装

装饰器

闭包

Python中几个比较常用的装饰器

首先举一个创建类的例

class 是声明类的关键字,human是类名,括号里的object是继承的父类(在Python2中如果无继承任何新式类,则为旧式类,其中object是新式类的基类)。Is_Animal是类变量,所有的类实例共享该变量,访问类变量可以直接通过类名而不需要实例化。self.name是类的一个属性,而self指向当前的类的实例对象,因此类的不同实例对象的属性可以有不同的取值。有self参数的函数说明该方法必须要实例后才可以调用。__init__(self)被称为构造函数,在实例化类时,一定会调用该方法。可以看到上面的例子中构造函数除了self,还需要一个参数name,因此在实例化该类时必须传入一个参数。

面向对象

Python的面向对象和Java的面向对象不太一样,学习过Java面向对象编程的pong友,可以对比Python的面向对象编程复习。下面详细简述python面向对象思想中的三要素实现:

面向对象--继承

Python支持多继承,而Java支持单继承。

Java支持单继承的好处是使得基础关系形成一棵树,继承关系比较清晰,不易产生混乱,不会产生冲突( 如果子类继承的两个父类有相同的方法,那么指类就不知道继承哪个方法了 )。但是当你编写的子类有着两个类的属性和方法时,单继承显得不那么方便了,Java中引入接口来解决这个问题。

Python支持多继承的好处是使得之类能轻松的获取多个父类的属性。但是要注意Python3和Python2的选择继承顺序的规则不一样。除了就近原则(如果父类找到该方法,则不需要继续父类的父类中查找该方法),Python3的是从左到右,广度优先;而Python2则是从左到右深度优先。举例如下

上面的代码在Python3中的输出为 C,因为它寻找继承的顺序是 [D,B,C,A] ,但由于C中已找到该方法,故就不需要去A中寻找继承。

上面的代码在Python2中的输出为 A ,因为它寻找继承的顺序是 [D,B,A,C] ,但由于A中已找到该方法,故就不需要去C中寻找继承。

若想在Python2中有着和Python3一样的继承规则的话,让A继承object类,以表明A及A的子类都是新式类。

面向对象--多态

有了继承之后就可以享受多态的好处,看下下面的例子

当你调用run_twice()函数时,随着你传入类的不同,输出结果也会不同,这样使得了程序有着更好的扩展性,当你想增加多一个Animal的之类的时候,你只需实现子类的run方法而不需要修改run_twice函数。即

对扩展开放:允许新增Animal子类;

对修改封闭:不需要修改依赖Animal类型的run_twice()等函数。

面向对象--封装

与Java的封装相比,Python的封装显得没有那么严格。

Java中封装通过访问修饰符实现并用this关键字来解决变量名与类变量命名冲突问题。例如,如果Java类的一个类变量或类方法的访问修饰符为private,那么类以外的地方都不能引用到该类变量或类方法,换句话说,该变量或方法对外屏蔽,以确保把不必要对外透露的细节封装起来,使得类与类之间的调用更简单而不需要在意实现的细节。

Python类若想对外屏蔽某属性或方法的话,在属性和方法名前加上 __(两个下划线),即可实现对外隐藏,但是这种隐藏不是严格的。例如

有类属性__name,不能直接访问__name是因为Python解释器对外把__name变量改成了_类名__name,我们仍可以通过_类名__name访问。但我们不应该这么做,既然有意去隐藏该属性,那么我们不应该主动的去破坏封装,而且不同Python的解释器可能会把__name改成不一样的变量名,若执意访问,可能会导致异常的出现。

装饰器

装饰器是Python中一个非常方便的工具,利用装饰器可以增大了代码的重用率。介绍装饰器必须先介绍关于函数的一些概念。高阶函数:一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

嵌套函数:在一个函数内定义另一个另一个函数,里面的函数叫作内层函数

并且我们还得了解变量的作用域L (Local) 局部作用域

E (Enclosing) 闭包函数外的函数中

G (Global) 全局作用域

B (Built-in) 内建作用域

变量会以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,全局找不到再去内建作用域中找,直到找到或者找不到(抛出异常)。并且局部变量会屏蔽外部变量。例子如下

变量不只有作用域还有生存周期,一般定义在函数内的变量会随着函数调用的结束而被销毁(形成闭包除外)。

闭包

闭包是由函数及其相关的引用环境组合而成的实体(即:闭包=函数+引用环境)例子如下

你会发现a在这里其实是表示了当x=3的时候的fun6,所以结果才会为9。

而装饰器的原理其实就是闭包,高阶函数利用闭包,把引用环境与传入的函数组成的闭包当作新函数返回。

但装饰器是有一定“副作用”

类装饰器的实现,以@property为例

Python中几个比较常用的装饰器

@property:@property把类方法改成类属性,实现存取器

@classmethod:可以用来定义类方法(不用实例就可以调用)

@staticmethod:主要是方便将外部函数集成到类体中,并且用staticmethod包装的方法可以内部调用,也可以通过类访问或类实例化访问。

本文首发于公众号「AI遇见机器学习」,更多干货可搜索[mltoai]或直接公众号名,欢迎关注!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值