1.两大编程思想的异同点:
面向过程 | 面向对象 | |
区别 | 事物比较简单,可以用线性的思维去解决 | 事物比较复杂,使用简单的线性思维无法解决 |
共同点 | 面向过程和面向对象都是解决实际问题的一种思维方式 | |
二者相辅相成,并不是对立的解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间复杂的关系,方便我们分析整个系统,具体到微观操作,仍然使用面向过程方式来处理 |
2.类:
- 定义:是由N多个对象抽取出“像"的属性和行为从而归纳总结出来的一种类别。
- 创建类的语法结构:(注:类名首字母要大写)
class 类名(): 或 class 类名:
pass pass
- 创建对象的语法格式:
对象名=类名()
- 类的组成:
(1)类属性:直接定义在类中,方法外的变量
(2)实例属性:定义在__init__方法中,使用self打点的变量
(3)实例方法:定义在类中的函数,而且自带参数self
(4)静态方法:使用装饰器@staticmethod修饰的方法
(5)类方法:使用装饰器@classmethod修饰的方法
class Student:
school="北京外国语学校" # 类属性
# 初始方法
def __init__(self,xm,age):
self.name=xm # 实例属性
self.age=age # 实例属性
# 实例方法
def show(self):
print(f"我叫{self.name},今年{self.age}岁了")
# 静态方法
@staticmethod
def sm():
print("静态方法不能调用实例属性和实例方法")
# 类方法
@classmethod
def cm(cls):
print("类方法不能调用实例属性和实例方法")
# 创建类的对象
stu=Student("杨娜娜",18)
print(Student.school) # 北京外国语学校
print(stu.name,stu.age) # 杨娜娜 18
stu.show() # 我叫杨娜娜,今年18岁了
Student.sm() # 静态方法不能调用实例属性和实例方法
Student.cm() # 类方法不能调用实例属性和实例方法
- 注意 :
实例属性和实例方法是对象名打.调用。
类属性,类方法,静态方法是类名打.调用。
静态方法和类方法不能调用实例属性和实例方法。
- 动态绑定属性和方法:
对象名.属性名=属性值
对象名.实例方法=方法名
stu.gender="男"
def introduce():
print("动态绑定的实例方法")
stu.fun=introduce
3.面向对象的三大特征:
- 封装:隐藏内部细节,对外提供操作方式。
- 继承:是在函数调用时,使用“形参名称=值”的方式进行传参,传递参数顺序可以与定义时参数的顺序不同。
- 多态:是在函数定义时,直接对形式参数进行赋值,在调用时如果该参数不传值,将使用默认值如果该参数传值,则使用传递的值。
4.类的权限控制:
- 权限控制:是通过对属性或方法添加单下划线、双下划线以及首尾双下划线来实现。
- 单下划线开头:以单下划线开头的属性或方法表示protected受保护的成员,这类成员被视为仅供内部使用,允许类本身和子类进行访问,但实际上它可以被外部代码访问。
- 双下划线开头:表示private私有的成员,这类成员只允许定义该属性或方法的类本身进行访问。
- 首尾双下划线:一般表示特殊的方法。
class Student:
def __init__(self,name,age,gender):
self._name=name # self._name是受保护的,只能本类和子类访问
self.__age=age # self.__age表示私有的,只能类本身去访问
self.gender=gender # 普通的实例属性,类的内部,外部以及子类都可以访问
def _fun1(self): # 受保护的
print("子类及本身可以访问")
def __fun2(self): # 私有的
print("只有定义的类可以访问")
def show(self): # 普通的实例方法
self._fun1() # 类本身访问受保护的方法
self.__fun2() # 类本身访问私有方法
print(self._name) # 受保护的实例属性
print(self.__age) # 私有的实例属性
stu=Student("张三",18,"女")
print(stu._name)
# print(stu.__age) # 不能访问
stu._fun1() # 子类及本身可以访问
# stu.__fun2() # 不能访问
# 访问私有属性和私有方法
print(stu._Student__age) # 18
stu._Student__fun2() # 只有定义的类可以访问
5.类中属性的设置:
- 使用@property修改方法,将方法转成属性使用
- 使用@gender.setter设置成可写属性
class Student:
def __init__(self,name,gender):
self.name = name
self.__gender = gender
# 使用@property修改方法,将方法转成属性使用
@property
def gender(self):
return self.__gender
# 将gender设置成可写属性
@gender.setter
def gender(self,value):
self.__gender = value
stu=Student("张三","男")
print(f"{stu.name}的性别是{stu.gender}") # 张三的性别是男
stu.gender="女"
print(f"{stu.name}的性别是{stu.gender}") # 张三的性别是女
6.类的继承:
- 继承:在Python中一个子类可以继承N多个父类,一个父类也可以拥有N多个子类,如果一个类没有继承任何类,那么这个类默认继承的是object类。
- 语法结构:
class 类名(父类1,父类2....父类N):
pass
# 父类
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def show(self):
print(f"姓名:{self.name},年龄:{self.age}")
# 子类1
class Student(Person):
def __init__(self,name,age,stuno):
super().__init__(name,age)
self.stuno = stuno
# 子类2
class Doctor(Person):
def __init__(self,name,age,department):
super().__init__(name,age)
self.department = department
stu=Student("张三",19,"1001")
stu.show() # 姓名:张三,年龄:19
doc=Doctor("李四",20,"外科")
doc.show() # 姓名:李四,年龄:20
7.类的多继承:
class FatherA:
def __init__(self,name):
self.name = name
def showA(self):
print("父类A中的方法")
class FatherB:
def __init__(self,age):
self.age = age
def showB(self):
print("父类B中的方法")
class Son(FatherA,FatherB):
def __init__(self,name,age,gender):
FatherA.__init__(self,name)
FatherB.__init__(self,age)
self.gender = gender
son=Son("张三",19,"女")
son.showA()
son.showB()
8.类中方法重写:
- 子类继承了父类就拥有了父类中公有成员和受保护的成员。
- 父类的方法法并不能完全适合子类的需要求这个时候子类就可以重写父类的方法。
- 子类在重新父类的方法时,要求方法的名称必须与父类方法的名称相同,在子类重写后的方法中可以通过super().xxx()调用父类中的方法。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print(f"我是{self.name},今年{self.age}岁了")
class Doctor(Person):
def __init__(self, name, age,department):
super().__init__(name, age)
self.department = department
def show(self):
super().show()
print(f"我的科室是{self.department}")
doc=Doctor("张三",20,"外科") # 创建对象时会自动调用__init__方法
doc.show()
9.object类:
- object:所有类直接或间接的父类;所有类都拥有object类的属性和方法。
- object类中特殊方法:
object类中特殊的方法 | 功能描述 |
__new__() | 由系统调用,用于创建对象 |
__init__() | 创建对象时手动调用,用于初始化对象属性值 |
__str__() | 对象的描述,返回值是str类型,默认输出对象的内存地址。 |
- 特殊方法:
运算符 | 特殊方法 | 功能描述 |
+ | __add__() | 执行加法运算 |
- | __sub__() | 执行减法运算 |
く,<=,== | __It__(),__le__(),__eq__() | 执行比较运算 |
>,>=,!= | __gt__(),__ge__(),__ne__() | 执行比较运算 |
*,/ | __mul__(),__truediv__() | 执行乘法运算,非整除运算 |
%, // | __mod__(),__floordiv__() | 执行取余运算,整除运算 |
** | __pow__() | 执行取余运算,整除运算 |
a=10
b=20
print(a+b) # 30
print(a.__add__(b)) # 30
- 特殊属性:
特殊属性 | 功能描述 |
obj.__dict__ | 对象的属性字典 |
obj.__class__ | 对象所属的类 |
class.__bases__ | 类的父类元组 |
class.__base__ | 类的父类,如果继承了N多个父类,只显示第一个父类 |
class.__mro__ | 类的层次结构 |
class.__subclasses__() | 类的子类列表 |
class A:
pass
class B:
pass
class C(A, B):
def __init__(self, name, age):
self.name = name
self.age = age
a=A()
b=B()
c=C("张三",20)
print("对象a的属性字典:",a.__dict__) # {}
print("对象b的属性字典:",b.__dict__) # {}
print("对象c的属性字典:",c.__dict__) # {'name': '张三', 'age': 20}
print("对象a所属的类:",a.__class__) # <class '__main__.A'>
print("对象b所属的类:",b.__class__) # <class '__main__.B'>
print("对象c所属的类:",c.__class__) # <class '__main__.C'>
10.类的深拷贝与浅拷贝:
- 变量的赋值:只是形成两个变量,实际上还是指向同一个对象。
- 浅拷贝:拷贝时,对象包含的子对象内容不拷贝,因此源对象与拷贝对象会引用同一个子对象。(源对象和拷贝对象的内存地址不一样,子对象的内存地址一样)
- 深拷贝:使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同。(源对象和拷贝对象的内存地址不一样,子对象的内存地址也不一样)
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self, cpu, disk):
self.cpu = cpu
self.disk = disk
cpu = CPU()
disk = Disk()
com=Computer(cpu, disk)
# 变量赋值
com1=com
print(com,com.cpu,com.disk) # <__main__.Computer object at 0x0000027CC583CAD0> <__main__.CPU object at 0x0000027CC579A5D0> <__main__.Disk object at 0x0000027CC5846FD0>
print(com1,com1.cpu,com1.disk) # <__main__.Computer object at 0x0000027CC583CAD0> <__main__.CPU object at 0x0000027CC579A5D0> <__main__.Disk object at 0x0000027CC5846FD0>
import copy
# 浅拷贝
com2=copy.copy(com)
print(com2,com2.cpu,com2.disk) # <__main__.Computer object at 0x0000024AE875D5D0> <__main__.CPU object at 0x0000024AE8766FD0> <__main__.Disk object at 0x0000024AE875CAD0>
# 深拷贝
com3=copy.deepcopy(com)
print(com3,com3.cpu,com3.disk) # <__main__.Computer object at 0x0000029EF31C5290> <__main__.CPU object at 0x0000029EF34CD450> <__main__.Disk object at 0x0000029EF34CDD90>
11.模块:
- 简介:
(1)在Python中一个后缀名为.py的Python文件就是一个模块。
(2)模块中可以定义函数、类等。
(3)模块也可以避免函数、类、变量等名称相冲突的问题。
(4)模块不仅提高了代码的可维护性,同时还提高了代码的可重用性。
(5)在给模块命名的时候要求全部使用小写字母,多个单词之间使用下划线进行分隔。
(6)如果自定义模块名称与系统内置模块名称相同,那么在导入时会优先导入自定义的模块。
- 模块的分类:
(1)系统内置模块:由开发人员编写好的模块,在安装Python解释器时一同安装成计算机。
(2)自定义模块:一个以.py结尾的文件就是一个模块,新建Python文件,实际上就是在新建模块。
自定义模块的作用:一是规范代码,将功能相同的函数、类等封装到一个模块中,让代码更易于阅读;另外一个目的与系统内置模块相同,即可以被其它模块调用,提高开发的效率。
- 模块的导入:
方式一 : import 模块名称 [as 别名]
方式二 : from 模块名称 import 变量/函数/类/*
# 方式一:
import my_info as info
print(info.name)
info.introduce()
# 方式二:
# from my_info import name,introduce
from my_info import *
print(name)
introduce()
12.Python中的包:
- 简介:含有_init_.py文件的文件夹(目录),可以避免模块名称相冲突的问题。
- 包的导入:
方式一 : import 包名.模块名
方式二 : from 包名 import 模块名
方式三 : from 包名.模块名 import 函数/变量等
# 方式一:import 包名.模块名
import admin.my_admin as admin
admin.info()
# 方式二: from 包名 import 模块名
from admin import my_admin as my
my.info()
# 方式三: from 包名.模块名 import 函数/变量等
# from admin.my_admin import info
from admin.my_admin import *
info()
- 主程序运行:
if __name__ == '__main__':
pass
13.Python中常用的内置模块:
在安装Python解释器时与解释器一起安装进来的模块被称为系统内置模块,也被称为标准模块或标准库。
标准库名称 | 功能描述 |
os模块 | 与操作系统和文件相关操作有关的模块 |
re模块 | 用于在Python的字符串中执行正则表达式的模块 |
random模块 | 用于产生随机数的模块 |
json模块 | 用于对高维数据进行编码和解码的模块 |
time模块 | 与时间相关的模块 |
datetime模块 | 与日期时间相关的模块,可以方便的显示日期并对日期进行运算 |
14.random模块:
random模块是Python中用于产生随机数的标准库。
函数名称 | 功能描述 |
seed(x) | 初始化给定的随机数种子,默认为当前系统时间 |
random() | 产生一个[0.0,1.0)之间的随机小数 |
randint(a,b) | 生成一个[a,b]之间的整数 |
randrange(m,n,k) | 生成一个[m,n)之间步长为k的随机整数 |
uniform(a,b) | 生成一个[a,b]之间的随机小数 |
choice(seq) | 从序列中随机选择一个元素 |
shuffle(seg) | 将序列seq中元素随机排列,返回打乱后的序列 |
15.time模块:
time模块是Python中提供的用于处理时间的标准库,可以用来进行时间处理、时间格式化和计时等。
函数名称 | 功能描述 |
time() | 获取当前时间戳 |
localtime(sec) | 获取指定时间戳对应的本地时间的struct time对象 |
ctime() | 获取当前时间戳对应的易读字符串 |
strftime() | 格式化时间,结果为字符串 |
strptime() | 提取字符串的时间,结果为struct time对象 |
sleep(sec) | 休眠sec秒 |
格式化字符串 | 日期/时间 | 取值范围 |
%Y | 年份 | 0001~9999 |
%m | 月份 | 01~12 |
%B | 月名 | January~December |
%d | 日期 | 01~31 |
%A | 星期 | Monday~Sunday |
%H | 小时(24h制) | 小时(24h制) |
%I | 小时(12h制) | 01~12 |
%M | 分钟 | 00~59 |
%S | 秒 | 00~59 |