menu ChaYedan
Python基础知识(三)
477 浏览 | 2020-02-05 | 阅读时间: 约 7 分钟 | 分类: Python | 标签: Python
请注意,本文编写于 967 天前,最后修改于 831 天前,其中某些信息可能已经过时。

面向对象

定义格式

class 类名:

​ 方法列表

备注:

定义方法时,在形参列表的第一个必须是self

self参数

对象不存储方法。方法中的self表示,正在调用方法的对象,哪个对象正在调用方法,self就表示哪个对象。

python解释器能够根据self的值确定哪个对象正在调用方法

相关函数

  • __init__方法:

魔法方法,Python解释器会在对象刚创建后立即调用这个方法。

初始化对象:给对象添加属性并赋值

通过self给对象添加属性:

​ self.属性名 = 属性值

属性是存储在对象里面的。

属性是属于对象的。

访问 属性:对象名.属性名

在对象的其他方法中,也能添加属性。但最好不要这么做,因为必须调用那个方法后,才有那个属性。

也能通过对象直接创建,但弊端跟在其他方法中创建属性一样。不要这么做。

综上,最好还是把属性全部加载init方法里

  • __str__方法:

跟java里面的tostring方法差不多,必须返回一个字符串。

默认返回对象的地址

  • __del__方法:

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

私有属性

这样的属性只能在类的里面访问,不能在类外面访问

定义格式

self.__属性名 = 属性值

访问格式

self.__属性名

私有方法

这种方法只能在类中调用。

​ Python中的私有属性和私有方法是伪的。当你在将属性或者方法命名成私有之后。解释器会对其做特殊的命名处理。

处理格式:
在名称前面加上_类名,即变成_类名__名称

即通过这样就可以在外界访问私有属性和私有方法

继承:

子类继承父类,就拥有父类中非私有的属性和方法

格式:

class A(object):

object即为父类。

object类

所有类的父类,默认所有类都继承了object类

重写父类的方法

在子类中定义一个同名的方法,一旦重写了这个方法,就不会在调用父类的方法了。

在子类中调用父类中被重写的方法

​ 怎么调用已经被重写的方法呢?

  • 父类名.方法名(self,实参1,实参2)
  • super().方法名(实参1,实参2, ...)
在子类中调用没被重写的方法
  • self.方法名
多层继承:

一层一层的继承

多继承:

一个子类同时继承多个父类,继承顺序从括号里从左向右继承,已经继承的方法就不会再继承

格式:

class 子类名(父类1,父类2,...)

实例属性和实例方法

实例属性指给实例对象添加的属性,实例属性是存储在实例对象里

实例方法指第一个参数是self的方法是实例方法,因为self指实例对象

类对象和类属性

类对象:一个类就是一个类对象,类的名字就类对象的名字

类属性:所有实例对象共享的属性,且可以定义为私有属性

类属性的定义格式:

  • 在类的地面,方法的外面定义

类属性的访问格式:

  • 实例对象名.属性名
  • 类名.属性名(推荐)

修改类属性:

  • 只能通过类对象(类名)修改。

类方法

定义方法时,在括号里写(cls),并且用装饰器@classmethod

@classmethod
def study(cls):
    pass

在类方法中,只能访问类属性和类方法,不能访问实例属性和实例方法

使用方式:

实例对象.类方法名(实参列表)

类名对象.类方法名(实参列表)

多态

在需要使用父类对象的地方,也可以使用子类对象, 这种情况就叫多态.

比如, 在函数中,我需要调用 某一个父类对象的方法, 那么我们也可以在这个地方调用子类对象的方法.

跟C++中,参数列表是父类指针一样,因为父类的指针可以用来指向子类对象或者父类对象,所以在子类中重写了的父类方法可以被调用,同样,父类中那个同名的函数也能被调用。因为在Python中,指针这个概念被弱化了,所以参数列表中的那个形参可以指任意对象,所以这里的多态,指参数传的是有继承关系的对象。

静态方法

定义方法:
使用@staticmethod装饰器

异常

概念

  • 程序在运行时,如果Python解释器遇到 到一个错误,会停止程序的执行,并且提示一些错误信息,这就是 异常
  • 程序停止执行并且提示错误信息 这个动作,我们通常称之为:抛出(raise)异常

捕获异常

简单的捕获
  • 在程序开发中,如果 对某些代码的执行不能确定是否正确,可以增加 try(尝试)捕获异常
  • 捕获异常最简单的语法格式:
try:
    尝试执行的代码
except:
    出现错误的处理
错误类型捕获
  • 在程序执行时,可能会遇到 不同类型的异常,并且需要 针对不同类型的异常,做出不同的响应,这个时候,就需要捕获错误类型了
  • 语法如下:
try:
    # 尝试执行的代码
    pass
except 错误类型1:
    # 针对错误类型1,对应的代码处理
    pass
except (错误类型2, 错误类型3):
    # 针对错误类型2 和 3,对应的代码处理
    pass
except Exception as result:
    print("未知错误 %s" % result)
  • 当Python解释器 抛出异常 时,最后一行错误信息的第一个单词,就是错误类型
捕获未知错误
  • 在实际开发中,为了能够处理复杂的异常情况,完整的异常语法如下:

提示:

  • 有关完整语法的应用场景,在后续学习中,结合实际的案例会更好理解
  • 现在先对这个语法结构有个印象即可
try:
    # 尝试执行的代码
    pass
except 错误类型1:
    # 针对错误类型1,对应的代码处理
    pass
except 错误类型2:
    # 针对错误类型2,对应的代码处理
    pass
except (错误类型3, 错误类型4):
    # 针对错误类型3 和 4,对应的代码处理
    pass
except Exception as result:
    # 打印错误信息
    print(result)
else:
    # 没有异常才会执行的代码
    pass
finally:
    # 无论是否有异常,都会执行的代码
    print("无论是否有异常,都会执行的代码")
  • else只有在没有异常时才会执行的代码
  • finally无论是否有异常,都会执行的代码
try:
    num = int(input("请输入整数:"))
    result = 8 / num
    print(result)
except ValueError:
    print("请输入正确的整数")
except ZeroDivisionError:
    print("除 0 错误")
except Exception as result:
    print("未知错误 %s" % result)
else:
    print("正常执行")
finally:
    print("执行完成,但是不保证正确")

异常的传递

  • 异常的传递 —— 当 函数/方法 执行 出现异常,会 将异常传递 给 函数/方法 的 调用一方
  • 如果 传递到主程序,仍然 没有异常处理,程序才会被终止

提示

  • 在开发中,可以在主函数中增加 异常捕获
  • 而在主函数中调用的其他函数,只要出现异常,都会传递到主函数的 异常捕获
  • 这样就不需要在代码中,增加大量的 异常捕获,能够保证代码的整洁

抛出异常(raise)

Python中提供了一个Exception异常类

抛出异常步骤
  1. 创建一个异常对象
  2. 使用raise关键字抛出异常对象

例如

def input_password():

    # 1. 提示用户输入密码
    pwd = input("请输入密码:")

    # 2. 判断密码长度,如果长度 >= 8,返回用户输入的密码
    if len(pwd) >= 8:
        return pwd

    # 3. 密码长度不够,需要抛出异常
    # 1> 创建异常对象 - 使用异常的错误信息字符串作为参数
    ex = Exception("密码长度不够")

    # 2> 抛出异常对象
    raise ex


try:
    user_pwd = input_password()
    print(user_pwd)
except Exception as result:
    print("发现错误:%s" % result)

模块

概念

  • 每一份源文件就是一个模块
  • 模块名 同样也是一个 标识符,需要符合标识符的命名规则
  • 在模块中定义的 全局变量函数 都是提供给外界直接使用的 工具
  • 模块 就好比是 工具包,要想使用这个工具包中的工具,就需要先 导入 这个模块

导入模块方式

  • import导入

    import 模块名1

如果模块的名字太长,可以使用 as 指定模块的名称,以方便在代码中的使用

import 模块名1 as 模块别名
  • from...import导入

    # 从 模块 导入 某一个工具
    from 模块名1 import 工具名

注意

如果 两个模块,存在 同名的函数,那么 后导入模块的函数,会 覆盖掉先导入的函数

导入之后,不需要通过模块名.,可以直接使用模块提供的工具(全局变量,函数,类)

模块的搜索顺序:

  1. 搜索 当前目录 指定模块名的文件,如果有就直接导入
  2. 如果没有,再搜索 系统目录

注意:给文件起名,不要和系统的模块文件重名

Python中每一个模块都有一个内置属性__file__可以查看模块的完整路径

原则

  • 一个独立的Python文件就是一个模块,在导入文件时,文件中所有没有任何缩进的代码都会被执行一遍。
  • 所以如果我们需要测试代码,就需要使用__name__属性

__name__是Python的一个内置属性,记录一个字符串

  • 如果是被其他文件导入,这个属性就是模块名
  • 如果是执行当前文件,__name____main__

所以在很多文件中就会看到以下格式的代码:

# 导入模块
# 定义全局变量
# 定义类
# 定义函数

# 在代码的最下方
def main():
    # ...
    pass

# 根据 __name__ 判断是否执行下方代码
if __name__ == "__main__":
    main()
知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,快来留言吧!