目录
1.面向对象
1.1 概念
面向过程:
优点:效率高,执行效率快
缺点:维护性,移植性差,表达不出一类的语意
面向对象:
优点:可读性,可移植性,可维护性高
缺点:执行效率慢
详细: Python面向对象_python 面向对象-CSDN博客
1.2 类对象
1.2.1 基础概念
语法:
class 类名():
def 函数(self):
pass
pass
注:self 为 自己
类属性:全类所共有,仅占用一份内存,更节省空间,类属性修改只能通过类对象修改,不能通过实例对象修改。实例对象修改-->创建实例属性
class plant(object):
a = 1
plant_1 = plant()
plant_2 = plant()
print("0 plant_1:",plant_1.a)
print("0 plant_2:",plant_2.a)
# 修改类属性 两个都修改
plant.a = 2
print("1 plant_1:",plant_1.a)
print("1 plant_2:",plant_2.a)
# 修改实例属性 只有一个修改
plant_1.a = 3
print("2 plant_1:",plant_1.a)
print("2 plant_2:",plant_2.a)
#运行结果
0 plant_1: 1
0 plant_2: 1
1 plant_1: 2
1 plant_2: 2
2 plant_1: 3
2 plant_2: 2
实例属性:单独开辟空间,每份占用内存
概念表达:
class run(object):
None1 = None #类属性
def __init__(self ,t ,s):
self.t = t
self.s = s
def V_running(self,V_error):
return self.s /self.t + V_error
def __str__(self):
return "t = %d,s = %d"%(self.t,self.s)
def __del__(self): # 析构函数 默认调用
if self.None1 == "b":
print(f"{self.None1}对象被删除")
else:
print("a对象被删除")
if __name__ == '__main__':
t = 10
s = 100
e = 1
# 创建对象
a = run(t,s)
b = run(s,t)
# 修改属性
b.None1 = "b"
# 调用方法
print("a类对象:",a.V_running(e))
print("b类对象:",b.V_running(e))
print("获取a对象的属性s:",a.s)
print("调用b对象的函数__str():",b.__str__())
print("获取b对象的属性None1:",b.None1)
print("获取a对象的属性None1:",a.None1)
#运行结果
a类对象: 11.0
b类对象: 1.1
获取a对象的属性s: 100
调用b对象的函数__str(): t = 100,s = 10
获取b对象的属性None1: b
获取a对象的属性None1: None
a对象被删除
b对象被删除
1.2.2 继承
语法(python 3.6):
class 类名1(object):
pass
class 类名2(类名1):
pass
class 类名3(类名1):
pass
class 类名4(类名2,类名3):
pass
类名2、类名3继承类名1,
类名2、3之间没有继承关系,
类名4继承类名2和类名3。
概念表达:
class 类名1(object):
def __init__(self,a):
self.a1 = 1
self.a = a
self.__a2 = 2 #私有属性
def 方法名1(self):
return "方法1打印结果:"+str(self.a)
def 方法名1_2(self):
return "方法1_2打印结果:成功打印!"
def __方法1_3(self): #私有方法
return "方法1_3打印结果:成功打印!"
def get_a2(self): #获取私有属性,也可构建函数修改
return "a2:"+str(self.__a2)
class 类名2(类名1):
def __init__(self,a,b):
#如果在__init__函数外先调用父类的属性和方法,父类会覆盖子类,所以在调用属性前先调用自己的子类初始化
类名1.__init__(类名1,a)
self.b1 = 2
self.b = b
def 方法名2(self):
return "方法二计算结果:"+str(self.b1 + self.b)
class 类名3(类名1):
def __init__(self,c):
self.c1 = 3
self.c = c
def 方法名3(self):
return "方法三打印结果:成功打印!"
class 类名4(类名2,类名3):
def __init__(self,a,b,c,d):
#当super()调用时,它将按照MRO列表的顺序搜索基类,即默认使用第一个父类的同名属性及方法。
#super()的第一个参数是当前类,第二个参数是基类。
类名2.__init__(self,a,b)
#super(类名4,self).__init__(a,b) #若使用这一行代码 默认使用第一个父类的同名属性及方法,与上一行代码效果相同
类名3.__init__(self,c)
self.d1 = 4
self.d = d
def 方法名2(self,is_add):
"""
:param is_add: 1:父类方法,2:子类方法
:return:
"""
#子类重写
if is_add == 1:
return super().方法名2()
elif is_add == 2:
return "方法4_二计算结果:"+str(self.d1 + self.d)
else:
return "参数错误!"
if __name__ == '__main__':
obj1 = 类名1(1)
obj2 = 类名2(1,2)
obj3 = 类名3(3)
obj4 = 类名4(1,2,3,4)
print(类名4.__mro__)
print("1",obj2.方法名1())
print("2",obj2.方法名1_2())
print("3",obj1.方法名1())
print("4",obj3.方法名1_2())
print("5",obj2.方法名2())
print("6",obj4.方法名3())
print("7",obj4.方法名2(2))
print("8",obj4.方法名1())
try:
print("9",obj2.__方法1_3())
except Exception as e:
print("9",e)
try:
print("10",obj1.__a2)
except Exception as e:
print("10",e)
print("11",obj4.get_a2())
#运行结果
(<class '__main__.类名4'>, <class '__main__.类名2'>, <class '__main__.类名3'>, <class '__main__.类名1'>, <class 'object'>)
1 方法1打印结果:1
2 方法1_2打印结果:成功打印!
3 方法1打印结果:1
4 方法1_2打印结果:成功打印!
5 方法二计算结果:4
6 方法三打印结果:成功打印!
7 方法4_二计算结果:8
8 方法1打印结果:1
9 '类名2' object has no attribute '__方法1_3'
10 '类名1' object has no attribute '__a2'
11 a2:2
1.2.3 多态
多态:Python中的多态如何理解?_python多态-CSDN博客
作用:让具有不同功能的函数可以使用相同的函数名,这样就可以用一个函数名调用不同内容(功能)的函数。
特点:
1、只关心对象的实例方法是否同名,不关心对象所属的类型;
2、对象所属的类之间,继承关系可有可无;
3、多态的好处可以增加代码的外部调用灵活度,让代码更加通用,兼容性比较强;
4、多态是调用方法的技巧,不会影响到类的内部设计。
示例:
class plant(object):
def show(self):
print("I am a plant")
class tree(plant):
def show(self):
print("I am a tree")
class apple_tree(tree):
def show(self):
print("I am an apple tree")
class apple(object):
def show(self):
print("I am an apple")
def why(obj):
obj.show()
if __name__ == '__main__':
# 创建对象
apple = apple()
tree = tree()
apple_tree = apple_tree()
plant = plant()
# 调用why()函数,并传入对象作为参数
why(apple)
why(tree)
why(apple_tree)
why(plant)
#运行结果
I am an apple
I am a tree
I am an apple tree
I am a plant
1.2.4 实例方法、类方法、静态方法
实例方法、类方法、静态方法:python类的实例方法、静态方法和类方法区别及其应用场景_python 子类的实例调用自身静态方法-CSDN博客
实例方法只能被实例对象调用,静态方法(由@staticmethod装饰的方法)、类方法(由@classmethod装饰的方法),可以被类或类的实例对象调用。
实列方法:实例方法,第一个参数必须要默认传实例对象,一般习惯用self。
类方法:需要用装饰器@classmethod 来标识,且第一个参数必须是类对象(一般:参数cls),它一般与类对象配合使用
静态方法:需要用装饰器@staticmethod 来进行修饰,参数没有要求。
class plant(object):
__a = 1
__b = 2
def get1_a(self): # 实例方法
return self.__a
@classmethod #类方法
def get2_b(cls):
return cls.__b
@staticmethod #静态方法,取消不必要的参数传递,减少内存占用和性能消耗
def get3_a():
return plant.__a
plant_1 = plant()
print(plant_1.get1_a())
print(plant_1.get2_b())
print(plant_1.get3_a())
#运行结果
1
2
1
1.3 异常
异常:Python异常及处理方法总结_python异常处理-CSDN博客
异常详细参考:Built-in Exceptions — Python 3.12.4 documentation
语法:
try:
错误代码
except:
报错异常后执行的代码
1.3.1 关键字
关键字 | 说明 |
---|---|
try...except | 捕获异常并处理 |
pass | 忽略异常 |
as | 定义异常实列(except MyError as e) |
else | 如果try中语句没有引发异常,则执行else语句 |
finally | 无论是否出现异常,都执行的代码 |
raise | 抛出/引发异常 |
1.3.2 捕获指定异常
通用异常类型表:Python异常捕获与处理_python异常捕获和处理-CSDN博客
摘自部分:
异常 | 描述 |
---|---|
BaseException | 所有异常的基类 |
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
ZeroDivisionError | 除(或取模)零 (所有数据类型) |
AssertionError | 断言语句失败 |
AttributeError | 对象没有这个属性 |
EOFError | 没有内建输入,到达EOF 标记 |
EnvironmentError | 操作系统错误的基类 |
IOError | 输入/输出操作失败 |
OSError | 操作系统错误 |
WindowsError | 系统调用失败 |
ImportError | 导入模块/对象失败 |
LookupError | 无效数据查询的基类 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
NameError | 未声明/初始化对象 (没有属性) |
UnboundLocalError | 访问未初始化的本地变量 |
ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
RuntimeError | 一般的运行时错误 |
NotImplementedError | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
Warning | 警告的基类 |
DeprecationWarning | 关于被弃用的特征的警告 |
FutureWarning | 关于构造将来语义会有改变的警告 |
OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
PendingDeprecationWarning | 关于特性将会被废弃的警告 |
RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
SyntaxWarning | 可疑的语法的警告 |
UserWarning | 用户代码生成的警告 |
1.3.3 自定义异常
自定义异常:python自定义异常_python 自定义异常-CSDN博客
语法示例:
class 自定义异常名(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return f"error:{self.message}"
# 测试自定义异常
try:
raise 自定义异常名("这是一个自定义异常")
except 自定义异常名 as e:
print(e)
#运行结果
error:这是一个自定义异常
1.4 模块和包
1.4.1 模块
import 模块名
from 模块名 import 功能名
from 模块名 import *
import 模块名.功能名 as 别名
from 模块名 import 功能名 as 别名
常用模块:Python常用模块大全(总结)_python模块-CSDN博客
1.4.2 模块创建
先定义一个文件,再以模块的方式导入该文件,再调用文件里的功能
示例:
创建文件add3.py:
def add(a,b):
print("add函数被调用了")
return a+b
#测试函数
if __name__ == '__main__': #指在当前文件被直接运行时,下面的代码块将被运行
print(add(1,2))
#运行结果
add函数被调用了
3
在创建另一个文件使用该模块:
import add3
# 测试add3.py
print(add3.add(2, 2))
#运行结果
add函数被调用了
4
1.4.3 模块搜索顺序
模块搜索顺序:深入理解Python解析器对模块位置的搜索顺序_ubuntu 不同python解析器 查找的模块路径是一样的吗-CSDN博客
定位模块
当你导入一个模块,Python解析器对模块位置的搜索顺序是:
- 当前目录
- 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
- 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/。
模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。
1.4.4 __all__
__all__:定义公开接口,当导入所有模块所有代码时,只能导入这个列表的成员
用法:Python中【__all__】的用法_python中all怎么用的-CSDN博客
示例:
add3.py
__all__ = ['add1']
def add1(a,b):
print("add1函数被调用了")
return a+b
def add2(a,b):
print("add2函数被调用了")
return (a+b)*-1
#测试函数
if __name__ == '__main__': #指在当前文件被直接运行时,下面的代码块将被运行
print(add1(1,2))
print(add2(1,2))
5.py
from add3 import *
# 测试add3.py
print(add1(1,1))
try:
print(add2(2, 2))
except:
print("add2函数未定义")
#运行结果
add1函数被调用了
2
add2函数未定义
1.4.5 包
包:python 制作python包,封装成可用模块_python 制作python包,封装成可用模块教程-CSDN博客
常用工具包:python中常用的工具包_python包-CSDN博客
导入包(同模块):
import 包名.模块名.功能名