面向对象 介绍
⾯向对象(oop) 是⼀种编程⽅法, 编程思想(即指导如何写代码), 适⽤于 中⼤型项⽬
⾯向过程也是⼀种编程思想, 适⽤于⼩型项⽬
⾯向过程 和 ⾯向对象 都可以实现某个编程的⽬的.
⾯向过程 考虑的是 实现的细节
⾯向对象 考虑的是 结果(谁能做这件事)
在python中,一切皆对象。
python 是一门面向对象的语言。面向对象最重要的概念就是类 (Class) 和实例(Instance),我们可以把类当做模板,而实例就是根据模板创建出来的一个一个对象。我们那汽车来举例,类相当于我们建造汽车的图纸(模板),而实际生活中,我开的车就是一个对象实例,你开的车也是一个对象实例。
面对对象除了类和实例,还有两个比较重要的概念:
- 属性: 表示这类东西具有的特征
- 方法: 表示这类东西可以做的事情。还是拿上面的汽车来记录,汽车具有的属性有 品牌,车龄等等。汽车具有的方法有 加速,刹车等等。
如何定义类
- 类: 是对具有相同特征或者⾏为的事物的⼀个统称, 是抽象的,不能直接使⽤
在pythnon中,类是通过 class 关键子来定义的
class 紧接类名 Car ,(object)表示这个类继承 object 类
那在类中是如何定义属性和方法的呢,示例如下:
- init__():是初始函数(与其他语言中的构造函数类似),它在创建一个对象实例时默认被调用,不需要手懂调用。所以,我们用它来初始化一些属性。
- self :我们看到无论是 init (),还是 broke()和 add()它的第一个参数都是 self,它表示创建实例的本身,在 init()函数内, self.brand =brand 就把属性绑定到了所创建的这个实例上。表示这个实例的有属性 brand并且他的值就是外部传过来的 brand.
而 broke()中的 self 也表示对象实例本身。可以理解为这个实例的的broke方法。在调用的时候 不用传该参数。
如何实例化类
python 中类的实例化也很简单,只要 实例名 = 类名()就可以了,我们还是那上面的 Car 类来举例,因为在 Car 类中 init()方法中初始化了属性(有除了self之外的参数),随意我们就必须传入以之向匹配的参数。示例如下:
class Car:
def __init__(self,brand,age):
self.brand=brand
self.age=age
def broke(self):
print(self.brand,'在刹车')
def add(self):
print(self.brand,'在加速')
car1 = Car('BMW',2)
print(car1.brand)
print(car1.age)
car1.broke()
car2= Car('BENZ',3)
print(car2.brand)
print(car2.age)
car2.broke()
BMW
2
BMW 在刹车
BENZ
3
BENZ 在刹车
三大特性
1.封装(Encapsulation)
封装是将数据和方法组合在一起的过程。类可以通过公有(public)和私有(private)的方式来封装数据和方法保护对象的内部实现细节。
2.继承(Inheritance)
继承是一种创建类的方法,新建的类可以继承一个或多个类;新建的类成为子类或者派生类,子类会遗传父类的属性和方法,被继承的类称为父类和超类。
如何用继承。我们还是拿上面的例子来说明,我们现在要穿个一个 mini_car 的类他拥有Car 类所有的属性和方法,另外它还能有其他的方法或属性。或者重构父类的方法(有不同的实现方式)。
我们来实例化一个对象
我们看到,我们在 Mini_car 中并没有定义add()方法,但仍能调用。要查看一个类是否是另一个类的子类,可以用内置的issubclass 函数
多个超类,多重继承,但尽量少用
3.多态(Polymorphism)
多态是一种对象的多种形态。简单来说,不同的对象可以对同一消息做出不同的响应。多态性可以提高代码的灵活
性和重用性。
在这个示例中,我们有一个父类Animal,它有一个名为 sound的方法但没有任何实现。然后我们定义了两个子类 Dog和 Cat,它们分别重写了 sound 方法,并添加了自己的实现。
然后我们定义了一个名为 make_sound 的函数,它接受一个Animal 类型的参数animal。在这个函数内部,我们调用animal的sound 法。
在主程序中,我们创建了一个 Dog对象 dog和一个Cat 对象 cat。然后我们分别将它们传递给 make sound函数,它们会根据各自的类型调用相应的 sound 方法。
这就是多态性的基本概念,当我们传递具有不同类型的对象时,它们会根据它们各自的类型来调用适当的方法。这使得我们可以使用相同的函数来处理不同类型的对象,实现更加灵活和可扩展的代码。
如何定义异常情况
python 用异常对象 (exception object) 来表示异常情况,遇到错误后,会引发异常,如果异常对象未被捕捉或处理,程序就会用所谓的回溯 (Tracebace) 执行终止示例如下:
因为除数不能为0,所以程序就会终止执行,所以下面的 print(111)就不会执行
异常也能主动触发的哦
我们可以通过 raise 引发异常,程序会自动创建异常实例
一些重要的异常类
异常名称 | 描述 |
---|---|
Exception | 常规错误的基类 |
AttributeError | 对象没有这个属性 |
IOError | 输入/输出操作失败 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
NameError | 未声明/初始化对象 (没有属性) |
SyntaxError | Python语法错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
让我们捕捉异常
-
单个 except python用 try—except— 来捕捉异常,示例如下: 就拿我们一开始的例子举例
和上面没有加 try—exception-- 比,系统没有抛出错误日志,上面这个例子用通俗的话来讲就是尝试着执行 1/0这操作,如果系统遇到错误并且是ZeroDivisionError,那么就执行 print(222)。
但如果我们我们写的不是 ZeroDivisionError 而是其他错误类型,那么还会执行print('222) 语句吗? 我们来试下:
系统抛出异常 ZeroDivisionError,而我们希望捕捉的是 IOError ,所以不会执行print(‘222’) -
多个except 如果预期会出现多种错误,那么可以用多个 except 去捕捉,示例
如下:
输入两个数相除,出现的异常也许是除数为0,又或者为输入的不为数字,所以这边写了两个 except,如果还会预期出现其他的错误,可以以此类推,在多增加except. -
用一个 except 捕捉多个异常 上面如果嫌多个 except 麻烦,可以用-个except 来代替,示例如下
except (ZeroDivisionError,ValueError) 起到的效果是一样的。 -
捕捉异常对象 如果我们想获取异常对象本身,可以用以下方法,示例如下:
-
全捕捉 如果我们不能确定程序会抛出什么异常,那么我们可以用全捕捉,这样个异常都不放过,示例如下:
在 except 后不跟如何异常类型就是全捕捉def -
else 在没有捕捉到异常情况下触发。 如果希望在程序一切正常,没有触发任何异常的情况下做些处理,可以用else,示例如下:
-
finally 与 try 联合使用不管异常有没有触发,都会执行 finally 语句块的内容。
模块
在Python中,一个.py文件就称之为一个模块(Module)
自己也能建立模块并给别人使用
在python中任何程序都可以作为模块存在。打开记事本,写入如下代码,保存为 hello.py,并存放在 D:\python 这个目录中
我们从示例看到,当第一次导入 hello 模块,系统会调用该模块里面的print('hello Mode ')并打印"hello Model"再次调用,并不打印"hello Model"这是为啥,因为导入模块并不意味着在导入时执行某些操作 (如打印) 。他们主要用于定义,比如变量,函数等,因此,因为只需要定义这些东西一次,导入多次模块和导入一次的效果是一样的。
导入模块还有其他的方式
- from 模块名 import 对象名[as 别名]使用这种方式仅导入明确指定的对象并且可以为导入的对象确定一个别名。这种导入方式可以减少查询次数,提高访问的速度,同时也可以减少程序员需要输入的代码量,不需要使用模块名作为前缀。
- from 模块名 import* 这种导入方式可以一次导入模块中通过 all 变量指定的所有对象。
all 变量,当一个模块中你不想把所有的属性和方法暴露给调用方,那么可以通过all 变量来指定想要暴露给调用方的属性 和方法。
很重要的__name__变量
当一个模块建立时,会自动加载一些内建变量,name 就是其中之一。它的作用就是可以显示一个模块的功能是被自己执行的还是被别的文件调用的。一个模块的功能被自己执行?最常见的就是一个模块中写了一个功能,在模块中测试这个功能(调动这个功能)。示例如下
运行Hello 模块文件,Python 解释器就会把_name 属性置为 main ,所以结果如下:
多个模块–>包
在模块之上的概念,为了方便管理而将文件进行打包。包目录下第一个文件便是init.py,然后是一些模块文件和子目录。常见的包的结构:
库
具有相关功能模块(包)的集合,库是python的特色之,python即具有功能强大的标准库(下载安装的python里那些自带的)、第三方库(由其他的第三方机构,发布的具有特定功能的模块)。
模块,包,库 实际都都是模块,只不过是个体和集体的区别。
介绍一些常用的标准库
1.sys模块
sys这个模块可让你能够访问与Pyhont解释器联系紧密的变量和函数,例如解释器的版本和路径,以及与 stdin、stdout 和 stderr 相关的信息。
常见属性:
名称 | 描述 |
---|---|
argv | 命令行参数,包括脚本名称 |
exit([arg]) | 退出当前的程序,可选参数为给定的返回值或错误信息 |
modules | 映射模块名字到载入的字典. |
path | 查找模块所在的目录的目录名称列表 |
platform | 类似win32的平台标识符 |
2.os模块
os模块是Python内置的一个用于与操作系统交互的模块,提供了许多与文件和目录操作、进程管理以及系统相关的功能,例如创建、移动和删除文件和目录,以及访问环境变量等。下面是一些os模块的常用函数和用法:
3.time模块
time获得当前时间,操作时间和日期,从字符串读取时间以及格式化时间为字符串。
4.random模块
该模块报货返回随机数的函数,可以用于模拟或者用于任何产生随机输出的程序
5.math模块
提供了一些数学函数,如三角函数、指数函数、对数函数等
>>> import math
>>> math.cos(math.pi / 4)
0.70710678118654757
>>> math.log(1024, 2)
10.0
6.json模块
用于处理JSON格式的数据,包括解析JSON字符串和生成JSON数据
7.csv模块
用于读写CSV文件(逗号分隔值),可以方便地处理表格数据
8.request模块
用于发送HTTP请求和处理相应,可以方便地进行通信
9.matplotlib模块
用于绘制图表和图形,可进行数据可视化。
10.pandas模块
提供了高性能、易用的数据结构和数据分析工具,广泛用于数据处理和分析。
11.numpy 模块
提供了高性能的数值计算功能,包括数组操作、线性代数、傅里叶变换等
12.re模块
提供了正则表达式的支持,用于字符串的模式匹配和替换
13.datetime模块
datetime 模块提供了更高级的日期和时间处理函数,例如处理时区、计算时间差、计算日期差等。
import datetime
#获取当前日期和时间
current_datetime = datetime.datetime.now()
print(current_datetime)
# 获取当前日期
current_date = datetime.date.today()
print(current_date)
# 格式化日期
formatted_datetime = current_datetime.strftime("%Y-%m-%d %H:%M:%S")
print(formatted_datetime) # 输出:2023-07-17 15:30:45
Open the File
Python 打开一个文件用 open()方法,语法如下open(name,[module[,buffering]])
- name为要打开文件的路径
- module位打开模式它和缓冲( buffering )参数都是非必填的。简单示例如下:
module 常用参数如下:
open函数的第3个参数(可选)控制着文件的缓冲。
0:无缓冲,所有读写操作直接针对硬盘。
1: 有缓冲,用内存替代硬盘
file的基本操作方法
1.读和写
文件(或流)最重要的方法就是提供或者接受数据
2.行的读写
- file.readline([n]) 从当前位置开始,直到一个换行符的出现(或者读取最多N个字符 字符)
- file.readlines() 读取一个文件的所有行
- writelines()给他一个字符串列表(可迭代的对象),他会把所有字符串写入文件,如果需要换行则要自己加入每行的换行符
3.关闭文件 close()
关闭文件 使用 open() 方法一定要保证关闭文件对象,即调用 close()方法。可以使用 try—finally 中使用,也可以使用 with open(XXX) as f:语法示例如下:
4.对文件内容进行迭代(循环处理)
- 按字节进行处理
- 按行进行处理
- 读取所有内容
如果文件不是太大,可以使用 read() 和 readlines()
如果文件很大,则使用fileinput 实现
在python近几个版本中,文件对象是可迭代(循环的)的,这就意味着可以直接在for循环中使用它们