• 面向对象


    面向对象1

    面向过程和面向对象概念
    • 面向过程:根据业务逻辑从上到下写代码(每一步都自己去实现)
    • 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程(不用具体到每一步,会调用就行。面向对象是基于面向过程的)
      面向对象有三种特性:1.封装  2.继承  3.多态
      

    C语言和C++语言都是编译过后才能生成(.exe)可执行程序后才可运行。
    python语言是直接运行,直到运行到出错地方才停止

    一、 类和对象

    A、 类

    类的概念

    类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象

    B、 对象

    对象的概念

    某一个具体事物的存在,在现实世界中可以是看得见摸得着的。

    C、 类和对象之间的关系

    类就是创建对象的模板

    二、 __init__() 方法

    方法类似于C++中的成员函数

    • __init__() 方法,在创建一个对象时默认被调用,不需要手动调用,与C++中的构造函数类似
    • __init__(self) 中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么 __init__(self) 中除了self作为第一个形参外还需要2个形参,例如 __init__(self, x, y)
    • __init__(self) 中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递进去

    三、 str() 方法


    • 在 python 中方法名如果是 (__xxx__()) ,那么就有特殊的功能,因此叫做"魔法"方法
    • 当使用print输出对象的时候,只要自己定义了 (__str__(self)) 方法,那么就会打印从在这个方法中 return 的数据。

    四、 self


    • 可以把 self 当做C++中类里面的this指针一样理解,就是对象本身的意思
    • 某个对象调用其方法是,python 解释器会把这个对象作为第一个参数传递给 self ,所以开发者只需要传递后面的参数即可。

    五、 隐藏数据

    修改对象属性(数据)有两种办法

    A、 直接通过对象名修改

    B、 通过方法间接修改

    应用题:老王开枪
    class Human:
        def __init__(self, name):
            self.name = name
            self.blood = 100
            self.gun = None
    
        def __str__(self):
            return self.name + "剩余血量为:" +  str(self.blood)
    
        def install_ball(self, clip, ball):
            clip.reserve_ball(ball)
    
        def install_clip(self, gun, clip):
            gun.link_clip(clip)
    
        def with_gun(self, gun):
            self.gun = gun
    
        def shoot(self, rob):
            self.gun.shoot(rob)
    
        def injured(self, hurt):
            self.blood -= hurt
    
    class Ball:
        def __init__(self, hurt):
            self.hurt_l = hurt
    
        def hurt(self, rob):
            rob.injured(self.hurt_l)
    
    class Clip:
        def __init__(self, capacity):
            self.capacity = capacity
            self.capacity_list = []
    
        def __str__(self):
            return "弹夹里面的数量为:" + str(len(self.capacity_list)) + "/" + str(self.capacity)
    
        def reserve_ball(self, ball):
            if len(self.capacity_list) < self.capacity:
                self.capacity_list.append(ball)
    
        def balls(self):
            # 判断当前弹夹中是否还有子弹
            if len(self.capacity_list) > 0:
                ball = self.capacity_list[-1]
                self.capacity_list.pop()
                return ball
            else:
                return None
    
    class Gun:
        def __init__(self):
            self.clip = None
    
        def __str__(self):
            if self.clip:
                return "枪里面装有弹夹"
            else:
                return "枪里面没有弹夹"
        def link_clip(self, clip):
            if not self.clip:
                self.clip = clip
    
        def shoot(self, rob):
            ball = self.clip.balls()
            if ball:
                ball.hurt(rob)
            else:
                print("没有子弹了...")
    
    # 创建一个人对象
    laowang = Human("laowang")
    print(laowang)
    
    # 创建一个弹夹
    clip = Clip(20)
    print(clip)
    
    # 装子弹
    i=0
    while i<5:
        ball = Ball(5)
        laowang.install_ball(clip, ball)
        i += 1
    
    # 打印子弹个数
    print(clip)
    
    # 创建一个枪对象
    gun = Gun()
    print(gun)
    
    # 把弹夹装进枪里面
    laowang.install_clip(gun, clip)
    print(gun)
    
    # 创建一个敌人
    rob = Human("rob")
    print(rob)
    
    laowang.with_gun(gun)
    
    laowang.shoot(rob)
    print(rob)
    print(clip)

    面向对象2

    一、 保护对象的属性

    如果有一个对象,当需要对其进行修改属性时,有两种方法
    • 对象名.属性名 = 数据 ----->直接修改
    • 对象名.方法名() ----->间接修改
    为了更好的保护属性安全,即不能随意修改,一般处理方式为
    • 将属性定义为私有属性,然后添加一个可以调用的方法提供调用

    • python 中没有像C++中public和private这些关键字来区别公有属性和私有属性
    • 它是以属性命名方式来区分,如果在属性名前面加了2个下划线,则表明该属性是私有属性,否则为公有属性(方法也是一样,方法名前面加2个下划线的话表示该方法是私有的)

    注意:如果直接使用( print(laowang.__age)会报错 ),可直接修改虽然不会报错,但是这个值不会被真正的写入

    二、 __del__() 方法

    • 创建对象后,python解释器默认调用 __init__() 方法; 当删除一个对象时,python解释器也会默认调用一个方法,这个方法为 __del__() 方法



    注意:当使用 del 删除变量指向的对象时,如果对象的引用计数不为1,那么此时只会让这个引用计数减1,只有当这个引用计数器变为1时再次调用del,此时才会把对象进行删除

    三、 继承

    • 子类在继承的时候,在定义时,小括号中为父类的名字
      注意:私有的属性、方法,不会被子类继承,也不能被访问

    四、 重写父类方法与调用父类方法

    所谓重写,就是子类中有一个和父类相同名字的方法,在子类中方法会覆盖掉父类中同名的方法


    五、 多态

    概念:定义时的类型和运行时的类型不一样,此时就成为了多态(同一条执行语句,不同的执行结果)



    注意1: 与 C 和 C++ 这些强类型语言不同的是,而python这类弱类型语言不用指定传入的参数类型,只要各类中含有被调用的方法,就能被执行
    注意2: 多态必须得重写

    补充:

    若类中有一个方法为 __test() 的私有方法, 那么我们可以如何访问呢?

    六、 类属性和实例属性

    • 实例属性: 也叫对象属性,归对象管理
    • 类属性: 它被类和对象所共有,和 C++ 中的静态成员变量类似。对于共有的类属性可以通过类或者对象直接访问



    注意1:当实例属性和类属性名相同时,用对象访问的属性将是实例属性(有实例属性就以实例属性为主,没有就访问类属性)

    问:既然能够通过对象名获取类属性的值,那能不能通过对象名向类属性修改呢?

    注意2:类属性的值不能通过对象名进行修改,如果修改本质是创建了一个和类属性同名的实例属性

    七、 类方法和静态方法

    概念:1.类方法需要用修饰器(@classmethod) 来标识其为类方法,第一个参数必须是类,一般以cls作为第一个参数。2.静态方法需要通过修饰器(@staticmethod)来进行修饰,静态方法不需要定义参数


    • 1.实例方法:用于修改实例属性
    • 2.类方法:用于修改类属性
    • 3.静态方法:用于打印菜单等工作

    面向对象3

    一、 工厂模式


    二、 __new__ 方法

    注意:在 (__init__)初始化之前还有一个 (__new__) 对象的创建,并且必须要有返回值

    三、 单例模式

    就是一个类只能创建出一个对象

    四、 异常

    概念:当 python 检测到一个错误时,解释器就无法继续执行了,反而出现了一些错误的提示,这就是异常(意料之中的错误)。

    A、 捕获异常



    注意:当 try 内部出现异常后,后面的语句将不会被执行

    B、 捕获多个异常


    注意:当捕获多个异常时,可以把要捕获的异常的名字放在 except 后,并使用元组的方式进行存储

    C、获取异常的信息描述



    result 存储异常的基本信息

    D、 捕获所有异常

    1 捕获所有异常


    2 捕获所有异常并存储异常信息


    E、 else


    注意:如果未出现异常才执行else的语句,如果try里面出现的异常没有被捕获则执行系统默认的异常

    F、 finally

    概念:在程序中,如果一个代码必须要执行,即无论是否产生异常都要执行,那么此时就需要使用finally。


    G、异常的传递


    H、 抛出自定义的异常

    概念:可以用 raise 语句来引发一个异常。异常对象必须有一个名字,并且是 Exception 类的子类。


    I、 异常处理中抛出异常


    五、 模块

    概念:python 中的模块就是一个py文件中整体的代码,与C语言的头文件类似

    A、 模块的制作

    概念:在 python 中每个python文件都可以作为一个模块,模块的名字就是文件名字。

    自己定义的test模块

    在main中调用test模块中的函数

    运行结果:

    注意:当使用 (import test) 的时候,会执行 test.py 中的所有函数。等价于直接执行 (python3 test.py)

    解决方案:使用 (__name__) 变量。若直接执行 (python3 test.py) 时,(__name__)变量值为(__main__), 若在 main.py 文件中含有 (import test) 时,(__name__)变量值为(test)

    自己定义的test模块

    main.py中的代码不变

    运行结果:

    B、 import

    在 python 中用关键字 import 来引入某个模块。比如要要引用模块 math ,就可以在文件最开始的地方用 import math 来引入

        引入模块:import module1, module2 ...
        调用函数:module1.函数名
    


    C、 form...import

    从模块中导入一个指定的部分到当前的命名空间中,不仅可以引入函数,还可以引入一些全局变量、类等。

        格式:from fbi import fbifuction   导入fbi模块的fbifuction的函数到当前命名空间
    


    注意:通过这种方式引入的时候,如果两个模块中的含有相同名称函数的时候,后面一次引用会覆盖前一次引入。

    D、 from...import *

    把一个模块的所有内容全部导入到当前的命名空间

        格式:from module import *
    

    E、 定位模块

    • 当导入一个模块,python解释器对模块位置的搜索顺序是:
    1. 当前目录
    2. python搜索在 shell 变量PATH下的每个目录
      可以使用:echo $PATH
    3. python 会查看默认路径, /usr/local/lib/python/
      在交互模式下使用os模块
    4. 模块搜索路径存储在 sys 模块的 sys.path 变量中。变量包含当前目录。
      在交互模式下使用sys模块的path

    例:当被调用的模块文件和执行文件不在同一个目录下,如何调用自定义模块
    /work/practice/python/008_module/TEST目录下的 test.py

    /work/practice/python/008_module目录下的 001_main.py

    执行结果:

    F、 __pycache__

    __pycache__ 里面存储的是缓存文件,即为了效率会把编译好的内容存放在 __pycache__ 目录下的 (.pyc)文件中。根据时间戳来决定被 import 后的文件是否被编译
    注意:只要 import 就有编译缓存

    G、 __all__

    注意:__all__只对 * 有效。 当没有 __all__ 的时候 使用 (from module import *) 会把模块中的函数都导入;当有 __all__时,只导入all里边的函数。----->用列表的方式赋值

    test.py 中的内容:

    main.py 中的内容:

    执行结果:

    六、 Python 中的包

    包的概念:将有联系的模块组织在一起,即放在同一个文件夹下,并且在这个文件夹下创建一个名字为 __init__.py 文件,那么这个文件夹就称为包。

    A、 使用(import 文件.模块) 的方式导入

    B、 使用(from 文件夹 import 模块) 的方式导入

    解决方法:在 msg 文件夹下创建 __init__.py 文件,并在文件中写入如下内容

    __init__ 文件内容:

    再次执行:

    注意: __init__.py 的作用:控制导入的模块

    七、 给程序传参数



    例:通过传入的参数来执行不同的函数

    八、 列表推导式

    所谓的列表推导式,就是轻量级循环创建列表。

    A、 基本的方法

    B、 再循环过程中使用if

    C、 2个for循环

    本质:双重for循环,用元组保存

    D、 3个for循环

    本质:三重for循环

    九、 set(集合)、list(列表)、tuple(元组)

    注意:set(集合) 中没有重复

    set、list、tuple之间的相互转换


    作用:使用 set ,可以快速的完成对列表或者元组中的元素去重复的功能。

    <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

  • 相关阅读:
    第十周作业
    第九周作业
    软件工程作业2
    自我介绍
    2019学习总结
    第二周作业
    十二周
    十一周
    第十周作业
    第九周作业
  • 原文地址:https://www.cnblogs.com/luosir520/p/11446420.html
Copyright © 2020-2023  润新知