类
具体语法
Class 类名:
变量 = 值 #类属性,公共属性
def 方法名(self,[参数]):#self代表实例(对象)本身
方法体
。。。
def 方法名(self,[参数]):
方法体
。。。
类名其实是一个标识符,建议使用 大驼峰命名法
类 是用来创建对象的直接运行没有任何效果
如果类里面没有任何代码就要加上 pass
创建对象
变量 = 类名()
由 类 创建的对象每次都会开辟 新的空间
使用 id()
查看创建后 对象的地址
先有 类 再有 对象
属性与方法
属性可以在 类里面添加 也可以在创建对象后添加
访问属性:
对象.属性名
#如果没有这个属性,就可以直接通过赋值来创建
对象.属性名 = 属性值
#此方法也可以修改属性
删除属性
del 对象.属性名
判断属性是否存在
bool = basattr(对象.属性名)#返回布尔
方法
基本语法:
对象.方法名() #一定假括号
- 一个方法可以多次调用
- 对象苦于调用使用的可以使用的方法
- 如果方法有返回值,就用变量去接收
dir()
- 查看对象由那些属性和方法
dir(对象)
初始化__init__()
每次开机都会初始化,在python里面的初始化方法__init__
是当你创建对象时,自动调用并执行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NGMnYqla-1679640031131)(C:\Users\Yuan\Desktop\python面向对象\文件__init__方法图解.PNG)]
class 类名:
def __init__(self,[参数]):
#绑定初始的属性
self.属性名1 = 值1
self.属性名2 = 值2
...
#创建对象
变量 = 类名()
#创建兑现时自动调用并执行
作用:绑定一些初始的属性
__str__()方法
固定名字的方法:__str__(self)
只有一个参数
通过print(对象),打印时自动调用__str__
方法,该方法返回(return)一个字符串
作用:用于自定义打印出的对象信息
注:如果在类中定义了__str__
没有返回值的话会报错
class 类名:
def __str__(self):
return '自定义对象信息'
对象变量 = 类名()
print(对象变量)
>>> 自定义对象信息
私有成员
在类中以两个下划线开头的成员被称之为私有成员
class 类名:
def __init__(self):
#私有属性
self.__属性名 = 值
def __方法名():
pass
作用:私有成员不能在 外部使用 ,只能在 类 的内部使用
-
可以在类里面访问后输出或者返回
用
dir()
输出时也会输出私有成员,但是会被python加上前缀z类名
-
一个属性一旦被私有化,在底层形成了
_类名__属性名
的属性名可以通过
_类名__属性名
直接访问
__del__()方法
当我们的对象被销毁的时候自动调用并执行
对象被销毁:
当代码执行完毕时候对象会被销毁
作用:用于对象被销毁的时候处理一些亲历下工作(比如文件关闭),由于python具有自动垃圾回收机制,所以不动手清理关系也不大
class 类名:
def __del__(self):
pass
del 类名.属性名/方法名 #可以删除属性或方法
主要查看对象到底在哪里被销毁
- 注:只有当所有对象的引用变量删除(del)时对象才被真正销毁,如果引用后的变量再被其他值引用,那也能被销毁
- 当对象没有被任何变量引用时,对象被销毁
__slots__方法
__slots__
限定绑定类属性,就是传入这个方法的 参数才能用作于类属性
class 类名:
__slots__ = (属性1,属性2,...)
实列:
该方法用于控制防止类的外面自定义属性导致报错
class Person(object):
__slots__ = ('name', 'age')
def eat(self, food):
print(food)
p1 = Person()
p1.name = 'Lucy' #只指定这两个属性,如果有其他属性写入就报错
p1.age = 18
# p1.height = 178 # AttributeError: 'Person' object has no attribute 'height'
@property装饰器
用作于把 类方法 转为 类属性 调用
如:show()
使用@property
修饰,则 show()
的调用:对象名.show
class Check(object):
@property
def show(self):
# 如果函数被@property修饰,最好设置返回值
return 'hello'
c = Check()
# c.show() #TypeError: 'str' object is not callable
print(c.show) # hello
如果被
@property
装饰,最好设置返回值
为了简化函数的调用,Python中通过 @property 和 @xxx.setter 分别修改两个函数。
注意:
- 两个函数的函数名尽量和被私有化的属性名保持一致
@xxx.setter
中的xxx
需要和被@property
修饰的函数名保持一致@property
修饰的函数用于获取值,@xxx.setter
修饰的函数用于修改值@property
和@xxx.setter
并不是需要同时出现,根据自己的需求进行选择@property
出现,@xxx.setter
可以不出现@xxx.setter
出现,@property
必须出现
@属性名.setter
也是装饰器的一种,用于修改值
class Decorate (object):
def __init__(self, name, age):
self.name = name
self.age = age
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
'''
name是被property装饰的name,目的是让name可以作为左值,name.setter后,就可以定义一个修改name的方法了,只能接收一个参数,用来作为等号的右值
'''
check = Decorate('张飞', 18)
print(check.name)
check.name = 'bob'
print(check.name)
>>> 张飞
>>> bob
@属性名.deleter
使用这个装饰之后,当属性被 del 属性
时这个装饰器中的方法会被调用
class Decorate (object):
def __init__(self, name, age):
self.name = name
self.age = age
@property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
@name.deleter
def name(self):
del self.__name # 删除属性
print('属性已被删除')
check = Decorate('张飞', 18)
print(check.name)
check.name = 'bob'
print(check.name)
del check.name
>>> 张飞
>>> bob
>>> 属性已被删除
继承
继承是发生在有从属关系的两个类上
即 子类继承父类
子类继承父类,子类直接可以使用父类上的属性和方法,不用重复再写,达到代码的复用
class 子类名(父类名):
#属性
#方法
- 如果没有任何父类继承,()可以不用写,要写就写(object) object:是python的初始父类,所有类都是它的子类
- 子类不能继承私有成员
单继承
一个类继承一个父类,就被成为i单继承
class Father(object):
pass
class Son(Father):
pass
在子类的构造函数中调用父类的构造函数
方式一:
super(当前类, self).__init__(参数列表)
方式二:
super().__init__(参数列表)
方式三:
父类名.__init__(self, 参数列表)
注意:在单继承中,三种方式都可以使用;在多继承中,只能使用方式三
**继承中的__slots__
**
__slots__
定义的属性仅对当前类的实例起作用,对继承的子类实例是不起作用
如果字类本身也有__slots__
属性,子类的属性就是自身的 __slots__
加上父类的 __slots__
多层继承(继承链)
class A(object):
pass
class B(A):
pass
class C(B):
pass
多继承
一个类可以继承多个父类
class 类名(父类1,父类2...):
pass
重写
发生在 继承关系 里
指子类中出现父类 相同名字 的属性或方法
重写的意义:当父类上的方法满足不了子类的时候,不能直接更改父类代码,只能在子类中重写
class Father(object):
def A(self):
pass
class Son(Father):
def A(self):
print('还是会运行子类')
pass
- 子类如何调用父类上的方法
super().父类方法名([实参])
多态
调用相同的方法,实线不同的功能
class Animal(object):
#动物类
def run(self):
print("不知怎么跑")
class Dog(Animal):
#狗类
def run(self):
print('四条腿汪汪跑')
class Snake(Animal):
#蛇类
def run(self):
print("梭梭的跑")
#创建对象
dog = Dog()
snake = Snake()
### 定义一个控制函数
def ganAnimal(animal):
#驱赶动物
animal.run()#先写入一个调用方法的代码
#调用函数
ganAnimal(dog)#把对象传输进去,在函数里调用类
ganAnimal(snake)
类属性与对象属性
类属性
因为 类 本身就是一个对象,所以也可以给他添加属性
#添加类属性
1.类名.属性名 = 值
2.class 类名(object):
类属性名 = 值
#访问类属性
类名.类属性名
类名.类属性名 = 新值
del 类名.类属性名
对象属性
每个对象都有属性,也被称之为实例属性
对象.属性名 = 值
self.属性名 = 值
区别
类属性 和 实例属性 的区别
类属性保存在类上面,所以所有的对象都能共享这个数据
非标准访问类属性:
对象. 类属性
使用共享属性可以降低内存的占用
类方法和静态方法
###类方法
class 类名(object):
@classmethod #装饰器声明类方法
def 类方法名(cls): #没有self
方法体
-
类方法只能使用类上的属性和方法
类名.类属性名
-
cls (class),代表的是类本身
cls.属性名
必须先用
@classmethod
声明
调用类方法:
类名.类方法名([实际参数])
不用创建对象直接通过类就能调用
静态方法
class 类名(object):
#用于声明静态的方法
@staticmethod #声明静态方法
def 静态方法名(): #无固定参数
方法体
- 静态方法:当方法中不使用类上的成员,这个时候就被定义为静态方法
调用方法
类名.静态方法名()
#__new__
创建对象的时候自动调用执行,优先级先于__init__
因为__new__
用作于在内存中开辟新的空间(底层会调用)
应用:可以稍微改变对象空间的创建过程
class 类名(object):
def __new__(cls,[形式参数]):
return super().__new__(cls)
#子类调用父类的方法用super(),所以将开辟的新对象空间返回,就会成为__init__的self,因为self其实就是类的空间的指针
#因为object里面有__new__,所以相当于重写
def __init__(self,[形式参数]):
pass
__new__
与__init__
的形式参数必须一致,因为都要默认调用- 对象 = 类名([实际参数])
- 可以通过 super().__new__(cls) 就能开辟新空间
- 最后将创建的对象空间返回
单例模式
是23种设计模式的一种
一个类的对象尤其只有一个,一个对象足以满足使用的需求,就没必要创建多个,浪费空间
以**__new__
** 来更改创建的内存空间,无论实列化多少个对象,他们的类中的内存地址都相同
# 案例:了解单列模式
class Singleton(object):
# 类属性
flag = False
singleton = None
def __new__(cls, *args, **kwarge):
# flag = False #定义一个控制变量,但如果写在这里每次调用都会开辟因为是 "局部变量"
# 因为我们要多次实例化但是只开辟一个空间,所以我们要拿一个变量来控制,但是不能在里面创建,因为在里面创建是局部变量下一次就每一列
if cls.flag == False:
cls.flag = True
cls.singleton = super().__new__(cls, *args, **kwarge)
return cls.singleton
else:
return cls.singleton
'''
解析:首先第一个实列化开辟空间,开辟后flag = True,属性singleton也保存了super().__new__
然后再创建第二个时,因为上一个flag = True,所以执行else,因为是返回singleton然后singleton
刚好保存的是上一个开辟的空间就达到了单列模式
'''
son1 = Singleton()
son2 = Singleton()
print(son1, son2)
异常
python代码中的错误,如果出现错误代码执行的时候就抛出异常,并且中断代码执行
## 异常处理
先捕获,再处理
try:
可能出错的代码块
except:
处理异常(打印,保存到文件,继续抛出)
###后面的语句无论有错继续执行
python中有一个基础异常类BaseException
所有他的子类都继承他
在代码中能够捕获并让代码继续执行的错误类型都是Exception
类或他的子类型
以下是系统异常类型,直接中断代码执行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-J46eCr35-1679640031133)(C:\Users\Yuan\Desktop\python面向对象\文件\异常的类型.PNG)]
try:
可能出错的代码块
except 异常类名1:
处理异常(打印,保存到文件,继续抛出)
except 异常类名2:
处理异常(打印,保存到文件,继续抛出)
except (异常类名3,异常类名4):
处理异常(打印,保存到文件,继续抛出)
try:
里面的代码块,只要一行错误,以下代码就不再继续执行
如果制定了错误类型,只会捕获该错误,其他的不会捕获
捕获所有错误
try:
可能出错代码
except Exception:
异常处理
获取系统提供的错误信息
try:
可能出错代码
except Exception as E:
异常处理
E:就是错误对象可以直接输出,获取之后系统就不会再报错
异常的完整语法
try:
可能出错代码
except 异常类名 as e:
捕获指定类型的错误
except (异常类名1,异常类名2):
同时捕获多种类型的异常
except Exception as e:
捕获所有异常
else:
没有异常的时候执行这里,告知我们的代码没有错误
finally:
无论如何都指向小河里
异常传递
如果没有捕获异常,异常就会向外抛出(如在函数里异常就会返回异常),只要最后一层捕获就能处理,如果没有捕获,异常正常抛出中断代码执行
模块和包
模块
一个 .py
文件就是一个模块
如何使用模块
- import 模块名 一次性导入模块中所有内容
- from 模块名 import 类/函数/变量 单独导入模块中的某个内容
- from 模块名 import * 一次性导入模块中的所有内容
- from 模块名 import 类/函数/变量,类/函数/变量,类/函数/变量… 单独导入模块中的所有内容
使用模块
模块名.类/函数/变量
注意:
from 模块名 import *
该语法是将模块中的所有内容全部导入,期望只导入部分
实现:
在模块最上面通过__all__=['内容1','内容2',...]
来定义那些内容能够被导入
包
包其实就是一个目录(文件夹)
标准的包下都有文件 __init__.py
是包的初始化文件
包的使用
- 导入包里面的模块
- import 包名,模块名
- 导入包中的指定模块
- from 包名 import 模块1,模块2
- from 包名.模块名 import 类/函数/变量
- from 包名.模块名 import *
模块名.方法()/属性
注意:
包中的__init__.py
才是用来控制包里的模块是否被导入,所以__all__
关键字是写在**__init__.py
** 里面
#__init__中
__all__ = ["模块名1","模块名2",...]
模块加强
模块的位置(存储位置)
1 . 内建模块(built-in)
在 python.exe
解释器里面
查看标准模块
先导入 import sys
然后 print(sys.module)
返回键值对,如果是内建就是 <built-in>
,如果不是内建就是标准的模块
2 . 标准模块
在python安装路径/Lib目录中,是自带的随时都可以使用
3 . 自定义模块
位置:主执行文件所在的当前目录下或者子目录下
4 . 第三方模块
位置:python安装路径/Lib/site-packages
5 . 自定义指定模块路径(用于改变第3条)
用法: import sys
sys.path.append(“自定义路径”) #添加到最后
sys.path.insert(0,“自定义路径”) #添加到最前面
解决模块错误问题
如果系统模块路径没有这个包,或者自定义的包不再执行文件目录下就会报错
python模块查找顺序
内建 -> 标准 -> 当前目录 -> 第三方 -> 自定义
如果模块重名了
根据导入顺序,如果你在与其他第三方模块重名之前导入那没有问题,但是如果你在导入后报错,那就需要在sys.path.append()
添加
pycharm是自动添加的
装饰器
在不改变原函数代码的基础上,添加性功能加强
原理
装饰器其实就是一个闭包函数
外函数的形式参数为原函数
内函数调用原函数
it__.py`** 里面
#__init__中
__all__ = ["模块名1","模块名2",...]
模块加强
模块的位置(存储位置)
1 . 内建模块(built-in)
在 python.exe
解释器里面
查看标准模块
先导入 import sys
然后 print(sys.module)
返回键值对,如果是内建就是 <built-in>
,如果不是内建就是标准的模块
2 . 标准模块
在python安装路径/Lib目录中,是自带的随时都可以使用
3 . 自定义模块
位置:主执行文件所在的当前目录下或者子目录下
4 . 第三方模块
位置:python安装路径/Lib/site-packages
5 . 自定义指定模块路径(用于改变第3条)
用法: import sys
sys.path.append(“自定义路径”) #添加到最后
sys.path.insert(0,“自定义路径”) #添加到最前面
解决模块错误问题
如果系统模块路径没有这个包,或者自定义的包不再执行文件目录下就会报错
python模块查找顺序
内建 -> 标准 -> 当前目录 -> 第三方 -> 自定义
如果模块重名了
根据导入顺序,如果你在与其他第三方模块重名之前导入那没有问题,但是如果你在导入后报错,那就需要在sys.path.append()
添加
pycharm是自动添加的
装饰器
在不改变原函数代码的基础上,添加性功能加强
原理
装饰器其实就是一个闭包函数
外函数的形式参数为原函数
内函数调用原函数
将内函数作为数据进行返回