面向对象
一,面向对象概念
1.1面向对象思想:万物皆对象
1.1,面向对象特征
1)封装 2)继承 3)多态
二,面向对象的语法
2.1类
1)什么是类?
类是对同一类事物共有的特征(属性)和行为(方法)的描述
2)语法:
class 类名(父类名):
属性|方法
#1,类的名字首字母大写,最好用大驼峰方式命名
#2,对象方法定义和函数类似,也可以设参数和返回值,但对象的第一个参数必须为self
#3,方法必须写在类的缩进中
2.2对象
1)什么是对象
对象是一个实实在在的事物,具有属性和方法,对象是根据类创建的,是类的实例化
语
2)对象的使用
对象的创建:
语 法:对象名=类名(参数)
访问对象:
对象.成员
使用属性:
添加属性:对象名.新属性名称=属性值
查看属性:对象名.属性名
修改属性:对象名.属性名=新值
删除属性:del 对象名.属性名
判断属性是否存在或属性上是否有值:hasattr(对象,'属性名称')
调用对象方法
对象.方法()
#对象中的self,谁调用,self就指的谁
2.3__init__,初始化方法
1)概念:__init__()叫作对象的初始化方法,在创建对象的时候自动调用执行.在类中定义,名字固定
2)执行时机:在创建对象的时候自动调用执行
3)作用:我们可以实现该方法,并且在该方法中进行初始化工作(例如:定义属性和设置属性值)
语法:
class 类名:
def __init__(self[,参数列表]):
4)例,通过初始化方法设定属性
class Student:
def __init__(selt):
self.name=name
self.age=age
作用:通过初始化方法绑定对象的属性.
2.4__str__方法:
1)作用,用来自定义对象的打印结果,让对象结果更人性化
2)例:class Student:
def __init__(selt):
self.name=name
self.age=age
def__str__(self):
retrun f"我的年龄为{name},我的地址为{age}"
三,类的继承
1,私有成员
1)什么是私有成员?
在成员(属性和方法)前面加上两个_,则表明该成员为私有成员,例如self.__age
2)私有成员只能在类中被访问到
作用:1,保证属性安全,不能被修改
2,提高封装性,因为私有成员不能被类外使用,用户使用时就只能执行用户需要的功能,提升用户体验
2__del__方法
在类中定义了一个固定名字的方法,该名字为__del__(不能够使别的名字)
执行时机: __del__()所在的对象空间从内存中销毁时,被python解释器自动调用执行。
该方法和__init__ () 是对立存在的。
格式:
def __del__ (self):
//方法体,通常用来完成对象销毁前的清理任务
__del方法调用时机:
1. Python脚本执行完后,python中所有的数据都会被销毁,包含对象,对象销毁__del__()方法执行
2. del删除存保存对象引用的所有变量
3. 保存对象引用的变量被设置成其他的值,当前对象的没有被其他变量所引用
3,继承
1)什么是继承
子类继承父类,子类可以直接使用父类上的成员
注:1,子类继承父类,子类可以添加自己的新功能
2,私有成员不能被继承
2)继承的特征
多继承:当一个子类需要使用多个父类上的属性和方法,但是多个父类之间没有直接关系,这个时候需要使用到多继承.
单继承:一个类继承另外一个类
多层继承:概念:一个C类,想要同时使用B,A类上的属性和方法,可以使用C继承B,B继承A.
4.重写
1)概念:子类中出现了和父类名字一样的成员(属性和方法),子类的成员就重写了父类成员
重写有方法重写和属性重写
2) 方法重写:当父类上的方法不满足子类的需求,而子类又不得不用的时候,就重写子类方法
语法:
super().父类方法名([实参])#调用父类方法
super(子类名,self).父类方法名([实参])#调用父类方法名的两种方法
def 子类方法名(self):
pass
5,多态
1)概念:在python语法中,可以在多个子类中重写父类的方法,这个时候所有的子类和父类中虽然都有相同名字的方法,但是实现的效果是不同的,这就是多态
6,类属性与实例属性
实例属性:在对象中定义的属性或在类中通过self定义的属性就是 实例属性
6,类属性和实例属性
1定义
类属性:在类(class)上绑定的属性称之为类属性,既然是类属性就应该归类所有。
语法:定义在类的里面方法的外面
class 类名(object):
#类属性的定义
类属性名 = 属性值
实例属性:我们通过对象或者在类里面通过self绑定的属性称实例属性
2,访问类属性
#访问一个类属性
类名.类属性名
#修改或者添加一个类属性
类名.类属性名 = 新值
注:1,类属性被所有对象共享,实例对象也能访问到类属性
2,千万不要将实例属性和类属性使用相同的名字,类属性和实例属性重名时,相同名称的实例属性将屏蔽掉类属性
7,类方法和静态方法
类方法的定义:
1. 必须使用装饰器@classmethod来标识方法为类方法
2. Python解释器自动将类对象传入给类方法的第一个参数,通常情况使用cls(class缩写)作为类方法的第一个形式参数,调用的时候不用传该参数
3. 类方法所有对象共享,所以可以通过类或者实例对象进行调用
类方法的使用好处:
1. 类方法不用创建对象直接可以通过类名调用,简单方便
静态方法:
1. 静态方法,需要通过修饰器@staticmethod来修饰,静态方法不需要额外定义参数
2. 静态方法可以通过类或者对象调用
class 类名(object):
# 实例方法
def 方法名(self,[形参]):
pass
# 类方法
@classmethod
def 类方法名(cls,[形参]):
# cls == class 调用的那个类
pass
# 静态方法
@staticmethod
def 静态方法名([形参]):
pass
# 调用
类名.类方法名()
类名.静态方法名()
四,new方法和单例模式
1,__new__:
执行时机: 创建对象的时候自动执行(先)
作用: 开辟对象空间
应用: 改变对象的创建过程
重写__new__, 改变原有的功能
语法:
class 类名(object):
def __new__(cls,*args,**kwargs):
# 返回创建的对象
# return object.__new__(cls)
return super().__new__(cls)
注意:
__new__方法接收的参数必须和__init__一致.
__init__:
执行时机: 创建对象的时候自动执行(后)
作用: 初始化实例属性
2,单例
# 1. 单例: 一个类只能创建出一个对象, 单例模式
class Singleton(object):
#定义一个类属性
__instance=None
__isinit=False
#父类上的__new__不能满足要求,要子类重写
def __new__(cls, *args, **kwargs):
"""
在类cls,上绑定一个私有的类属性__instance 表示对象空间
如果cls.__instance 为None说明没有绑定,就绑定
如果cls.__instance 不为None,说明已经绑定
无论如何都要返回创建的对象空间
:param args:
:param kwargs:
:return:
"""
if cls.__instance is None:#如果类属性__instance为空,
cls.__instance=super().__new__(cls)#调用父类上的__new开辟空间,并保存在类属性上
return cls.__instance
def __init__(self,name):
if Singleton.__isinit is False:
self.name='张三'
Singleton.__isinit =True
san=Singleton('张三')
si=Singleton('李四')
print(san,si)
print(san.name,si.name)
3,异常总结
- 异常: 就是python中的错误对象
- 特点: 异常一旦抛出, 将终止代码进行运行.
- 捕获异常: 异常捕获后,代码可以继续执行
```python
try:
# 可能出现的错误的代码
except 异常类名 as e:#e可以是任意变量
print(e) #获取错误信息
else:
# 没有异常的时候执行这里的代码
finally:
# 无论如何都执行这里的代码
特殊:
try:
# 可能出现的错误的代码
except:
print(e) #获取错误信息
try:
# 可能出现的错误的代码
except (异常类1,异常类2...) as e:
print(e) #获取错误信息
```
- 异常的传递: 异常如果没有被捕获, 可以向外依次进行传递.
- 异常的抛出:
```python
raise 异常类对象 =====> raise 异常类("错误信息")
```
- 自定义异常
```python
"""
步骤:
1. 继承 Exception 类
2. 重写__init__()
3. 重写__str__()
"""
"""自定义一个异常类"""
class PasswordError(Exception):
def __init__(self,msg,length):
"""重写__init__"""
self.msg = msg
self.length = length
def __str__(self):
"""重写__str__"""
return f"{self.msg},规定必须大于等于{self.length}"
# 登陆函数
def login(username,password):
# 参数判断
if len(password) < 6:
# 密码必须大于等于6位,小于就是错误, 抛出异常
# print("xxxxxx")
raise PasswordError("密码错误",6)
# 正常执行
print("正常登陆")
try:
# 验证登陆
login("张三","123")
except Exception as e:
print(f"错误信息:{e}")
```
五,模块的导入
``````python
5.1)1模块定义:每一个py文件就是一个模块
注:模块和包的命名符合标识符的命名规范
2,包:包就是一个文件夹,储存多个模块.标准包中有一个__init__py文件.
导入模块:
import 模块名
from 模块名 import 方法,函数,变量,属性
注:import 后面跟什么,就用什么
模块测试代码书写位置:
魔术变量:name,其值有python自动赋值
1)当前文件为主执行文件时,name=‘main’
2)当前文件为被导入文件,name__的值为模块名.
if name==‘main’
5.2 模块中的all
from 模块名 import *:一次性导入模块中的所有属性
缺点:一次导入太多,不一定都用,浪费空间
解决:通过__all=[‘函数名’,‘变量’]限制只能导入列表中的内容
*代替的是from模块名import 成员名中的成员名
5.2模块的定义
模块的查找路径:
1)系统规定死的路径
先后顺序:
内置模块路径(python.exe)中,任意地方都能使用
系统标准模块路径(python安装路径\lib目录中)任意地方都能使用
主执行文件所在的当前目录
第三方安装包的安装路径(pip install pymySQL):python安装路基/lib/site-packages,任意地方都能使用
2),自定义路径
任意指定一个路径作为包/模块的查找路径
方式:
import sys
sys.path
sys.path.append(‘新目录路径’)
sys.path.insert(索引,‘新目录路径’)
注:pycharm自动将项目跟目录添加到sys,path中,原本是没有的
六,包的使用
``````python
1,包的使用:
只能通过from模式导入
from 包名 import 模块名
from 包名.模块名 import 函数|类|变量名
from 包名.模块名 import *
注:包不能通过from 包名 import 模块名 方式一次性导入所有模块
使用from 包名.模块名 import *时,必须采用__all__方法限定
七,函数range
range():函数用于生成指定范围的对象(可迭代对象)
使用方式:
obj=range(start,end,step)
start:默认0
end:设置:包前不包后
step:默认
使用方式:转换成列表 list(obj)
直接遍历:for …in
八,给程序传递参数
1,给程序传递参加:指给python.exe传递参数
传递参数的方式:python.exe 脚本路径 参数1 参数2
接收参数的方式:
import sys
变量=sys.argv [参数的索引号]
八:列表推导式
1,概率:列表推导式根据指定表达式用于快速生成列表
语法:
变量=[表达式 for 临时变量 in 容器 简单的if语句]#简单if 语句指 if 条件 else 条件,没有elif
九.集合
1,集合可以用于去重
2,集合可以运算
集合1&集合2 求交集
集合-集合2 求差集
集合1|集合2 求并集