Python回顾面向对象
【一】面向过程开发和面向对象开发
【1】面向过程包括函数和面条
- 包括面条版本一条线从头穿到尾
- 学习函数后开始对程序进行分模块,分功能开发
- 学习模块化开发,我们就可以对我们的功能进行分类开发
- 建一个功能的包---->在模块(py)文件中开发相应的功能 ---->通过包的init文件将我们想对外开放的功能导出去 ATM的分层,易于扩展和开发
【2】面向对象开发
- 将一类的功能和数据整合到一起就是---类
- 通过实例化类能得到相应的对象---不仅包括了所有的公共部分,还可以自定制对象的属性和方法
【二】什么是类,什么是对象
【1】类的演示
- 类就是数据和程序的结合体
- 对象是类的具体实现
# 动物类---》猫类
这是一个简单的 Python 类 MyCat,具有一个构造方法 __init__。这个类表示猫的实体,每只猫有一个名字和颜色。__init__ 方法是一个特殊的方法,用于初始化对象的属性。在这里,它接受两个参数 name 和 color,并将它们分别赋值给实例属性 self.name 和 self.color。如果不提供初始化方法 __init__ 或者提供的初始化方法中没有对属性进行赋值,那么创建类的实例时,实例将没有任何属性。这可能会导致在访问实例属性时出现 AttributeError,因为属性没有被定义。
# object(新式类)
class MyCat(object):
def __init__(self, name, color):
# 对属性进行赋值
self.name = name
self.color = color
class Cat(object):
mycat = "小猫咪"
def __init__(self, name, color):
self.name = name
self.color = color
def read(self):
print(f'{self.name} is {self.color}')
obj = Cat(name="xiaomi", color='yello')
obj.read()
【2】对象的演示
(1)__init__的四部推导过程
(2)实例化类得到对象
class MyCat(object):
def __init__(self, name, color):
self.name = name
self.color = color
# 实例化类得到对象
cat = MyCat(name="小米", color="yello")
【3】如何查看属性
# 类属性包括数据属性和函数属性
class MyCat(object):
# 类的数据属性
home = "小猫比"
def __init__(self, name, color):
self.name = name
self.color = color
# 函数属性
def speak(self):
print(f'{self.name}正在喵喵叫')
cat = MyCat(name="小米", color="yello")
print(dir(MyCat)) # 查看类属性,只能包括为初始化对象之前的所有属性
print(dir(myCat))# 查看对象属性,包括实例化得到对象时传入的属性
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'home', 'speak']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'color', 'home', 'name', 'speak']
【4】如何查看名称空间?
class MyCat(object):
# 类的数据属性
home = "小猫比"
def __init__(self, name, color):
self.name = name
self.color = color
# 函数属性
def speak(self):
print(f'{self.name}正在喵喵叫')
cat = MyCat(name="小米", color="yello")
# 查看名称空间
print(MyCat.__dict__)
print(cat.__dict__)
# 查看类的属性
print(cat.home)
{'__module__': '__main__', 'home': '小猫比', '__init__': <function MyCat.__init__ at 0x000001F9DB8DB7F0>, 'speak': <function MyCat.speak at 0x000001F9DBBC5BD0>, '__dict__': <attribute '__dict__' of 'MyCat' objects>, '__weakref__': <attribute '__weakref__' of 'MyCat' objects>, '__doc__': None}
{'name': '小米', 'color': 'yello'}
小猫比
# 对象是基于类来得到的,对象就继承了所有类里面的属性
# 查看类和对象的名称空间发现是一个字典类型,但是又和字典有所区别
# 对象可以 .属性 取值/修改值
【三】绑定方法与非绑定方法
【1】绑定方法:向目标对象(类和对象)绑定的方法
# 绑定给对象的方法:我们正常书写,self自动补全都是对象的绑定方法
class Person(object):
def read(self):
print("正在读书")
# 绑定给类的方法:使用装饰器修饰一下自动补全cls就是类的绑定方法
class Person(object):
def read(self):
print("正在读书")
@classmethod
def write(cls):
print("正在写书")
【2】非绑定方法:既不给类也不给对象的方法,就是普通方法
# 使用装饰器staticmethod修饰一下,既不给类也不给对象不会自动补全任何参数的方法
class Person(object):
def read(self):
print("正在读书")
@classmethod
def write(cls):
print("正在写作业")
@staticmethod
def run():
print("非绑定方法")
【3】调用绑定给对象的方法
class Person(object):
def read(self):
print("正在读书")
@classmethod
def write(cls):
print("正在写作业")
@staticmethod
def run():
print("非绑定方法")
p = Person()
p.read()
# 正在读书
类调用绑定给对象的方法 : 第一个参数必须是一个对象
# 在python里面一切皆对象,虽然可以放任意类型,但是为了可扩展性,所以我们选择放实例化得到的对象
Person.read(p)
【4】调用绑定给类的方法
1.# 对象去调用,第一个参数默认检索到创建对象自己的类,将这个类传进去
p = Person()
p.write()
# 正在写作业
2.# 类调用,哪个类调用的我,就会默认将此类作为第一个参数传入
Person.write()
# 正在写作业
【5】非绑定方法
对象和类都可以任意调用,因为就是一个普普通通的函数
Person.run()
p = Person()
p.run()
【四】面向对象三大特性:封装、继承、多态--->派生、组合
【1】封装
- 封装就是将某些数据隐藏起来,不被外界所使用,保护隐私
【2】如何修改封装起来的数据?
- 接口,我们通过开放指定的函数接口,让用户通过指定的接口调用传参数,然后修改属性
【3】如何实现封装?
__变量名
class Person(object):
__name = "人类"
# __变量名会将我们想要隐藏的属性隐藏起来
# 在第一次实例化类得到对象的时候会对这个变量名做一次变形
# 变形成_Person__name
def __init__(self, name, age):
self.name = name
self.age = age
def __speak(self):
print(f"{self.name}正在发言!")
# 如果想要修改隐藏的属性可以开发一个接口
p = Person(name="lisi", age=18)
print(Person.__dict__)
print(p)
# 实现了对name和speak的封装
{'__module__': '__main__', '_Person__name': '人类', '__init__': <function Person.__init__ at 0x000001C83FD7B7F0>, '_Person__speak': <function Person.__speak at 0x000001C840065BD0>, '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
p.__name = 'opp'
print(p.__dict__)
# 生成新的属性
{'name': 'lisi', 'age': 18, '__name': 'opp'}
# 通过接口修改隐藏属性
class Person(object):
__name = "人类"
def __init__(self, name, age):
self.name = name
self.age = age
def __speak(self):
print(f"{self.name}正在发言!")
# 如果想要修改隐藏的属性可以开发一个接口
def set_name(self, name):
# 在类内部可以任意调用我自己封装起来的和没有封装起来的属性
if not name.isupper():
raise ValueError(f"{name}必须大写")
self.name = name
# p = Person(name="lisi", age=18)
# print(Person.__dict__)
# p.__name = 'opp'
# print(p.__dict__)
# 通过接口修改隐藏属性
p = Person(name="lisi", age=18)
p.set_name(name="opp")
# 报错:
ValueError: opp必须大写
p = Person(name="lisi", age=18)
p.set_name(name="OPP")
print(p.__dict__)
# {'name': 'OPP', 'age': 18}
【4】封装有哪些用处?
- 封装为了保护我们的隐私数据不被外部发现
- 封装为了更好的修改和添加
- 为了更好的模块化开发我们的功能
【五】三大特性之继承
【1】单继承和多继承
- 父类和子类的概念
- 父类就是所有子类公共的属性
- 子类继承了父亲的属性,但是可以延伸出自己的属性和功能(派生)
class Animal(object):
def run(self):
...
def speak(self):
...
# 单继承:一个子类只继承一个父类
class Dog(Animal):
def eat(self):
...
# 多继承:一个子类可以继承多个父类
class RedDog(Dog,Animal):
def set_color(self):
...
# 查看子类继承的所有父类
class Animal(object):
def run(self):
...
def speak(self):
...
# 单继承:一个子类只继承一个父类
class Dog(Animal):
def eat(self):
...
# 多继承:一个子类可以继承多个父类
class RedDog(Dog, Animal):
def set_color(self):
...
# 查看子类继承的所有父类 __base__:只能看到我子类继承的第一个父类,__bases__可以看到我子类继承的所有父类
print(RedDog.__base__)
print(RedDog.__bases__)
<class '__main__.Dog'>
(<class '__main__.Dog'>, <class '__main__.Animal'>)
【2】深度优先和广度优先
# python2 里面才会分深度优先和广度优先
# 深度优先就是一条道走到黑
# 广度优先就是先走支路。最后走主路
# python3默认都是广度优先
class A:
...
class B(A):
...
class C(B):
...
class D(C):
...
class E(C):
...
class F(E, D, A):
...
# 如果按照深度优先:F--> E -->C -->B -->A -->D
# 如果是广度优先 : F -->E -->D --->C --> B ---> A
# 记不住,太乱了,分不清,但是还想知道查找顺序
print(F.__mro__)
# (<class '__main__.F'>, <class '__main__.E'>, <class '__main__.D'>, <class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
【3】新式类和经典类
- python2分经典类和新式类,新式会继承object基类
- p3不分,都是新式
【4】抽象类
- 抽象类中定义的函数必须被子类重写或继承,在子类中如果不存在父类中的抽象方法就会报错。
import abc
class Animal(object, metaclass=abc.ABCMeta):
@abc.abstractmethod
def speak(self):
...
@abc.abstractmethod
def eat(self):
...
class Person(Animal):
# 必须将Animal里面的两个方法拿进来
def eat(self):
...
def speak(self):
...
p = Person()
【5】派生
- 继承父类的所有属性并且衍生出自己的属性
class Animal(object):
def __init__(self, animal_name):
self.animal_name = animal_name
# super超类:将父类的init 方法重新初始化到我当前的类中
# 如果父类中有和子类重名的属性,super在后,得到的属性就是当前父亲中存在的属性
class Dog(Animal):
def __init__(self, name, animal_name):
super().__init__(animal_name)
self.name = name
【6】面向对象之多态
- 一个事物具有多种形态我们就叫他多态
- 对于代码来说,子类可以继承父亲衍生出自己的独特的方法就叫多态
class Duck(object):
def eat(self):
...
def speak(self):
...
class RoleDuck(Duck):
def eat(self):
...
def speak(self):
...
class TangDuck(Duck):
def eat(self):
...
def speak(self):
...
【7】鸭子类型(术语)
# 概念:长得像鸭子,走路也像鸭子,叫起来也像鸭子,那他就是鸭子
# 在这里你就可以把鹦鹉抽象成鸭子
【8】组合
- 组合其实就是将我们所学到的所有数据类型集合到一起
- 类可以包容八大基本数据类型
- 包容函数
class Student(object):
def __init__(self, name):
self.name = name
class Student(object):
def __init__(self, name):
self.name = name
# 放一个类的对象
self.stu = Student(name='zhang')
self.class_info = {}
self.class_info_class = []
【六】反射
【1】什么是反射
反射是一种程序可以访问、检测和修改其本身状态或行为的能力。
在 Python 中,反射主要指通过字符串的形式操作对象的属性。
通过字符串的形式操作对象相关的属性。
python中的一切事物都是对象(都可以使用反射)
【2】反射的方法
- getattr(object, name[, default])
- 获取对象的属性值,如果属性不存在,可提供默认值。
- hasattr(object, name)
- 判断对象是否具有指定属性
- setattr(object, name, value)
- 设置对象的属性值
- delattr(object, name)
- 删除对象的属性
class Person(object):
def __init__(self, name):
self.__name = name
# 使用装饰器将 函数属性包装成数据属性
@property
def name(self):
# 一定要有返回值,并且返回值是字符串
return self.__name
# 修改属性
@name.setter
def name(self, value):
print(value)
self.__name = value
# 删除属性
@name.deleter
def name(self):
print(f'删除')
p = Person(name='zhang')
print(p.name())
print(p.name)
p.name = 'opp'
del p.name
class Person(object):
def __init__(self, name):
self.name = name
# 绑定给对象的方法
def run(self):
print('这是run方法')
# 实例化类得到一个具体的对象
p = Person(name='zhang')
【需求】
# 给一个对象,判断一下对象中是否存在该属性
# 如果存在则继续取出来,如果不存在则设置 进去
def check_func(obj=None, key=None, value=None):
# 【1】检验属性是否存在
if not hasattr(obj, key):
print("不存在该属性")
setattr(obj, key, value)
print('设置属性完成')
else:
return getattr(obj, key)
p = Person(name='opp')
print(check_func(obj=p, key='name'))
print(check_func(obj=p, key='gender', value="female"))
print(p.gender)
Python回顾面向对象的更多相关文章
- python基础——面向对象编程
python基础——面向对象编程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...
- Python的面向对象3
接下来,我们接着讲Python的面向对象,在上一次的博客中,我们详细介绍了类与对象的属性,今天,我们来详细介绍一下面向对象中的方法! 1.定义实例方法 一个实例的私有属性就是以__开头的属性,无法被外 ...
- Python的面向对象2
我们接着讲解Python的面向对象 1.初始化实例属性 在现实生活中,一种类型的实例会具有相同的某些属性,把这些实例划分为一个类型,则这些实例必然有相似的部分.但是,在创建实例之后,我们一个一个的为实 ...
- Python的面向对象1
今天,我们来介绍Python的面向对象编程,其实面向对象并不陌生,在C++ ,Java ,PHP中也有大量使用! 好了,我们来步入正题! 那什么是面向对象编程呢? 1. 面向对象编程是一种程序设计 ...
- My way to Python - Day05 - 面向对象-思维导图
My way to Python - Day05 - 面向对象 思维导图
- Python进阶---面向对象的程序设计思想
Python的面向对象 一.面向过程与面向对象的对比 面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优 ...
- Python之面向对象一
引子 小游戏:人狗大战 角色:人和狗 角色属性:姓名,血量,战斗力和性别(种类) 技能:打/咬 用函数实现人打狗和狗咬人的情形 def Dog(name,blood,aggr,kind): dog = ...
- python基础——面向对象进阶下
python基础--面向对象进阶下 1 __setitem__,__getitem,__delitem__ 把对象操作属性模拟成字典的格式 想对比__getattr__(), __setattr__( ...
- python基础——面向对象进阶
python基础--面向对象进阶 1.isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 ...
- python基础——面向对象的程序设计
python基础--面向对象的程序设计 1 什么是面向对象的程序设计 面向过程的程序设计的核心是过程,过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优 ...
随机推荐
- yum 安装失败解决思路$releasever(curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown error")
问题 公司使用刀片机的系统版本是CentOS 7.9.2009(Core),本人在重新安装虚拟机时,也使用对应的系统版本,在安装软件时,yum无法正常使用,一开始觉得,centos的release版本 ...
- tensorflow语法【tf.matmul() 、loc和iloc函数、tf.expand_dims()】
相关文章: [一]tensorflow安装.常用python镜像源.tensorflow 深度学习强化学习教学 [二]tensorflow调试报错.tensorflow 深度学习强化学习教学 [三]t ...
- C/C++ Npcap包实现数据嗅探
npcap 是Nmap自带的一个数据包处理工具,Nmap底层就是使用这个包进行收发包的,该库,是可以进行二次开发的,不过使用C语言开发费劲,在进行渗透任务时,还是使用Python构建数据包高效,这东西 ...
- LeetCode刷题日记2020/8/22
题目 24点程序 描述 你有 4 张写有 1 到 9 数字的牌.你需要判断是否能通过 *,/,+,-,(,) 的运算得到 24. 示例 1: 输入: [4, 1, 8, 7] 输出: True 解释: ...
- 【算法】C语言程序编程模拟实现strlen函数和strcpy函数
C语言程序编程模拟实现strlen函数和strcpy函数(超详细的注释和解释) 求个赞求个赞求个赞求个赞 谢谢 先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说 ...
- ABC 311 A - E
ABC 311 A - E 不提供代码 A 题意:求一个字符串的第一个 ABC 最早出现的位置,可以打乱顺序,可以间隔 建立三个变量,然后以此判断即可,直到三种字符都出现就可以了 B 题意:给定每个人 ...
- MySQL中 int(11)和int(10)有没有区别!!
结论:int(11) int(3) int(20) 若不勾选填充0,那么效果统统一样,若勾选了填充0:查询出来的效果 会是这样: int(11) 00000000123 int(3) 123 ...
- 鸿蒙开发游戏(三)---大鱼吃小鱼(放置NPC)
效果图 添加了一个NPC(小红鱼),玩家控制小黄鱼 鸿蒙开发游戏(一)---大鱼吃小鱼(界面部署) 鸿蒙开发游戏(二)---大鱼吃小鱼(摇杆控制) 鸿蒙开发游戏(三)---大鱼吃小鱼(放置NPC) 鸿 ...
- JS leetcode 两数之和 II - 输入有序数组 题解分析
壹 ❀ 引 我在JS leetcode 两数之和 解答思路分析一文中首次解决两数之和等于目标值的问题,那么今天遇到的是两数之和的升级版,题目为leetcode167. 两数之和 II - 输入有序数组 ...
- NEMU PA 2-3 实验报告
课程地址:https://www.bilibili.com/video/BV1yC4y1s74C 一.实验目的 了解ELF符号表的解析 进一步完善调试器的功能,理解编译器的设计原理 二.实验步骤 在P ...