Python基础之面向对象
引言,学习面向对象之前先讨论一下编程思想 目前我们学了两种编程思想。一是面向过程编程即流程,面向过程就是按照固定的解决流程解决问题,比如编写注册功能、登录功能、转账功能等,需要列举出每一步的流程,并且随着步骤的深入问题的解决思路越来越简单,然后指定出该问题的解决方案,用函数关键字def来完成面向过程的编程。二是面向对象编程,有点类似于造物主的感觉 只需要造出一个个对象至于该对象将来会如何发展跟程序员没有关系也无法控制,比如游戏人物。用关键字class来定义出类来完成面向对象的编程。这两种编程思想没有优劣之分需要结合实际需求而定、实际上这两种编程思想是彼此交融的只是占比不同。如果需求是注册登录 人脸识别那肯定使用用面向过程更合适。如果需求是游戏人物肯定是面向对象更合适。面向对象并不是一门新的技术为了好区分定义出来了独有的语法格式。那么本篇文章接下来详细的研究一下编程思想之一面向对象。
一、面向对象之类与对象
- 对象:数据与功能的结合体 是面向对象的核心 必须先定义出类才能用对象
- 类:多个对象相同数据和功能的结合体 主要是为了节省代码
1.类与对象的创建以及调用
class 类名:
'''代码注释'''
对象公共的数据
对象公共的功能
"""
class 是定义类的官关键字
类名的命名跟变量名几乎一直 但是要首字母大写
数据是变量名与数据值得绑定
功能是方法其实就是函数
"""
类在定义阶段就会执行类体代码 但是属于类的局部名称空间 外界无法直接调用
类和对象访问数据或者功能 可以统一采用句点符
类名加括号就会产生对象 并且每执行一次都会产生一个全新的对象
2.对象独有的数据和功能
'''对象独有数据'''
1.直接利用对象点名字的方式
obj1 = Student()
obj1.__dict__['name'] = 'almira'
obj1.age = 18
obj2 = Student()
obj2.__dict__['name'] = 'Alina'
obj2.age = 29
2.将添加对象独有数据的代码封装成函数
def init(obj,name,age):
obj.name = name # obj.__dict__['name'] = name
obj.age = age # obj.__dict__['age'] = age
3.将上述方法绑定给特定类的对象
class Student:
def init(obj,name,age):
obj.name = name # obj.__dict__['name'] = name
obj.age = age # obj.__dict__['age'] = age
4.自动触发的方法
class Student:
def __init__(self,name,age):
self.name = name # obj.__dict__['name'] = name
self.age = age # obj.__dict__['age'] = age
5.类中如果有双下init方法 意味着类加括号需要传参数
obj = Student('almira', 18)
'''对象独有的功能'''
1.也是直接在全局定义函数 然后给对象
def func():pass
obj = Student()
obj.func = func
2.面向对象的思想 放到类中
3.对象的绑定方法
类中定义的方法既可以说是对象公共的方法 也可以是对象独有的方法
哪个对象来调用 谁就是主人公
二、动静态方法 在类体中定义函数的三种方式
1.类中直接定义函数 默认绑定给对象 类调用有几个参数传几个阐述 对象调用第一个参数就是对象自身
class Student:
shcool_name = '天津财经大学'
def func1(self):
print('天才学子')
obj = Student()
# 1.绑定给对象的方法
obj.func1()
Student.func1(123)
2.被@classmethod修饰的函数 默认绑定给类 类调用第一个参数就是类自身 对象也可以调用并且会自动将产生该对象的类当做第一个参数传入
class Student:
school_name = '天津财经大学'
@classmethod
def func2(cls):
print('是不是蒙了呢', cls)
obj = Student()
# 2.绑定给类的方法
Student.func2() # fun2(Student)
obj.func2() # func2(Student)
3.普普通通的函数 无论是类还是对象调用 都必须自己手动传参
class Student:
school_name = '天津财经大学'
@staticmethod
def func3(a):
print('哈哈哈,我很烦',a)
obj = Student()
# 1.静态方法
Student.func3(123)
obj.func3(321)
三、面向对象三大特征之继承
1.继承的含义
在编程世界中继承表示类与类之间资源的从属关系 比如 类A继承类B
2.继承的目的
在编程世界中类A继承类B就拥有了类B中所有的数据和方法使用权
3.继承得本质
继承的本质就是对某一批类的抽象,从而实现对现实世界更好的建模
4.继承的实操
class Son(Father):
pass
'''括号里面可以写其他类名Son就继承了Father'''
# 继承其他类的类 Son 称为子类派生类
class Son(F1, F2, F3):
pass
'''可以多继承 在括号内的类名用逗号隔开即可'''
# 被继承的类 Father F1, F2, F3 称为父类、基类、超类
5.名字的查找顺序
- 不继承:对象自身>>>产生对象的类
- 单继承:对象自身>>>产生对象的类>>>类的父类们
- 多继承:对象自身>>>产生对象的类>>>类的父类们
四、面向对象三大特征之封装
封装:就是将数据和功能'封装'起来
隐藏:将数据和功能隐藏起来不让用户直接调用 而是开发一些接口间接调用从而可以在接口内添加额外的操作
伪装:将类里面的方法伪装成类里面的数据
class C1:
__name = 'almira'
def __func(self):pass
'''也有可能会出现单个下划线开头的变量名也表示隐藏的意思或者没有'''
class C2:
@property
def BMI(self):pass
五、面向对象三大特征之多态
多态其实就是一种事物的多种形态 面向对象中的多态的意思是 一种事物可以有多种形态但是针对相同的功能应该定义相同的用法 这样无论拿到的是那个具体的事物 都可以通过相同的方法调用功能
'''多个类如果有相似之处 那么里面针对相似的功能应该起相同的名字'''
class Memory:
def read(self):pass
class Disk:
def read(self):pass
'''鸭子类型实际案例'''
class QQ:
def send(self):pass
class Wechat:pass
def send(self):pass
class Email:pass
def send(self):pass
class Msg:pass
def send(self):pass
六、面向对象之反射
反射是指利用字符串操作对象的数据或方法,从另一个角度分析的话反射能够将面向对象的代码与用交互起来
hasattr() 判断对象是否含有某个字符串对应的属性名或方法名
getattr() 根据字符串获取对象对应的属性名或方法名
setattr() 根据字符串对象设置或修改数据
delattr() 根据字符串删除对象里面的名字
七、面向对象的魔法方法
魔法方法:类中定义的双下方法 不需要人为调用 在特定的条件下会自动触发运行 比如双下init方法创建空对象之后自动触发给对象添加独有的数据如下列举出来了一些魔法方法名称个、和它的功能解释
__init__ 对象添加独有的数据的时候自动触发
__str__ 对象被执行打印操作的时候自动触发
__call__ 对象加括号调用的时候自动触发
__getattr__ 对象点不存在的名字的时候自动触发
__getatribute__ 对象点名字就会自动触发
__setattr__ 给对象添加或者修改数据的时候自动触发
__enter__ 当对象被当做with上下文管理操作的开始自动触发
__exit__ 当with上下文管理语法运行完毕之后自动触发
__new__ 可以产生空对象
__dict__ 以字典方式打印所有属性
八、创建类的两种方式
# 方式1:使用关键字class
class Student:
school_name = '天津财经大学'
def func1(self):pass
print(Student)
print(Student.__dict__)
# 方式2:使用元类type
格式:type(类名,类的父类,类的名称空间)
cls = type('Student', (object,), {'name': 'almira'})
print(cls)
print(cls.__dict__)
评论区