一、面向对象
什么是面向对象?
面向过程编程思想与面向对象编程思想对比:
- 面向过程编程思想:
核心是 “过程”二字,过程是指解决问题的步骤,即先干什么再干什么!
基于该编程思想编写程序,就好比在设计一条工厂流水线,一种机械式的思维方式
优点:
将复杂的问题流程化,进而简单化
缺点:
牵一发而动全身,程序的可扩展性差
- 面向对象编程思想:
核心是 “对象” 二字,对象指的是“特征与技能”的结合体。
基于该编程思想编写程序,就好比把自己当做一个上帝在创造世界,一种“上帝式”的思维方式
优点:
可扩展性高
缺点:
面向对象编写程序的复杂程度比面向过程高
注意:编程思想仅仅是一门思想,与任何技术无关
二、类
1、什么是类?
类指的是类型、类别。
在两种角度去看待类:
- 现实世界中:
- 先有一个个对象,经过社会的文明发展,随之总结出类,对象是实际存在的,而类是抽象产生的
- python程序中:
- 必须先由类,再通过调用类产生对象
对象指的是“特征与技能”的结合体, 类指的是一系列“对象之间相同的特征与技能”的结合体
2、如何定义类?
如何写类并产生对象:
- 先从现实世界中通过一个个对象总结出类
- 然后再定义类,后调用产生对象。
比如 “选课系统”:
选课系统 – 学生类:
- 学生对象1:
特征:
- 姓名:tank
- 性别:female
- 年龄:95
- 学校:家里蹲
技能:
- 技术:python
- 学习:learn
- 选课:course
- 学生对象2
特征:
- 姓名:jason
- 性别:female
- 年龄:99
- 学校:家里蹲
技能:
- 技术:python
- 学习:learn
- 选课:course
3、定义类的语法
语法:
class 关键字:帮你产生类
class 类名:
- 对象之间相同的特征
- 学校
school = “家里蹲”
- 对象之间相同的技能
- python
def Python():
pass
- learn
def Learn():
pass
- course
def Course():
pass
类名的规范:
- 驼峰命名法(推荐)
定义一个学生类并对属性进行增删查改:
<span style="font-family:"><span>#</span><span> 定义一个家里蹲学生类</span> <span>class</span> JldStudent: <span>#</span><span> 类名指向的是类的内存地址</span> <span>#</span><span> 学生相同的特征</span> <span>#</span><span> 在类中的特征(即变量)称之为“属性”</span> school = <span>"</span><span>OldBoy</span><span>"</span> <span>#</span><span> 注意:在类内部定义函数,会默认产生一个参数self</span> <span>#</span><span> 学生相同的技能(即函数)称之为“方法”</span> <span>def</span> learn(self): <span>#</span><span> self此处当做一个形参</span> <span>print</span>(<span>"</span><span>learning...</span><span>"</span><span>) </span><span>#</span><span> 查看类的名称空间</span> <span>print</span>(JldStudent.<span>__dict__</span><span>) </span><span>print</span>(JldStudent.<span>__dict__</span>[<span>"</span><span>school</span><span>"</span>]) <span>#</span><span> 可调用属性</span> <span>print</span>(JldStudent.<span>__dict__</span>[<span>"</span><span>learn</span><span>"</span>]) <span>#</span><span> 获取learn方法对象</span> JldStudent.<span>__dict__</span>[<span>"</span><span>learn</span><span>"</span>](123) <span>#</span><span> 方法对象+(),相当于执行learn函数(方法)</span> <span>#</span><span> 类提供了一种特殊获取名字的方式 “类名.名字”的方式</span><span> #</span><span> 查</span> <span>print</span><span>(JldStudent.school) JldStudent.learn(</span>12<span>) </span><span>#</span><span> 改</span> JldStudent.school = <span>"</span><span>Cld</span><span>"</span> <span>print</span><span>(JldStudent.school) </span><span>#</span><span> 删</span> <span>del</span><span> JldStudent.school </span><span>#</span><span> print(JldStudent.school) # AttributeError: type object "JldStudent" has no attribute "school"</span> <span>#</span><span> 增</span> JldStudent.age = 18 <span>print</span>(JldStudent.age)</span>
www#gaodaima.com来源gao@!dai!ma.com搞$$代^@码网搞代码
执行结果:
<span style="font-family:">{<span>"</span><span>__module__</span><span>"</span>: <span>"</span><span>__main__</span><span>"</span>, <span>"</span><span>school</span><span>"</span>: <span>"</span><span>OldBoy</span><span>"</span>, <span>"</span><span>learn</span><span>"</span>: <function JldStudent.learn at 0x0000026D35CD97B8>, <span>"</span><span>__dict__</span><span>"</span>: <attribute <span>"</span><span>__dict__</span><span>"</span> of <span>"</span><span>JldStudent</span><span>"</span> objects>, <span>"</span><span>__weakref__</span><span>"</span>: <attribute <span>"</span><span>__weakref__</span><span>"</span> of <span>"</span><span>JldStudent</span><span>"</span> objects>, <span>"</span><span>__doc__</span><span>"</span><span>: None} OldBoy </span><function JldStudent.learn at 0x0000026D35CD97B8><span> learning... OldBoy learning... Cld </span>18</span>
4、类的名称空间
- 类的名称空间:
在定义阶段时产生,会将类中所有的名字,扔进类的名称空间
- 函数的名称空间:
在调用函数时产生,函数调用结束后销毁
三、对象
1、对象的产生
对象名=类名() —> 调用类产生对象
类的名称空间在定义时产生,对象的名称空间在调用类时产生
调用类产生对象的过程称之为类的实例化,对象称之为一个类的实例
定义一个类:
<span style="font-family:"><span>class</span><span> Student: </span><span>#</span><span> 学校 ---> 属性</span> school = <span>"</span><span>Jld</span><span>"</span> <span>#</span><span> 技能 ---> 方法</span> <span>def</span><span> learn(self): </span><span>print</span>(self) <span>#</span><span> 打印输出为 <__main__.Student object at 0x00000000021B6248>,是一个对象</span> <span>print</span>(<span>"</span><span>learning...</span><span>"</span><span>) </span><span>#</span><span> 获取对象,产生对象</span> obj =<span> Student() </span><span>print</span>(obj) <span>#</span><span> 打印输出为 <__main__.Student object at 0x00000000021B6248>,也是一个对象</span> <span>#</span><span> 对象调用类内部的名字(属性)</span> <span>print</span><span>(obj.school) </span><span>#</span><span> 对象调用类内部的函数(方法),无需传入参数:会将对象当做第一个参数传给该函数(方法)</span> obj.learn() <span>#</span><span> 对象的绑定方法,无需传参</span></span>
执行结果:
<span style="font-family:"><<span>__main__</span>.Student object at 0x000001BE191C6908><span> Jld </span><<span>__main__</span>.Student object at 0x000001BE191C6908><span> learning...</span></span>
由对象来调用类内部的函数,称之为对象的绑定方法。
对象的绑定方法特殊之处:会将对象当做第一个参数自动传给该函数(方法),所以对象调用类内部的函数时无需传参
2、为对象添加独有的属性
定义一个类:
<span style="font-family:"><span>class</span><span> Student: </span><span>#</span><span> 学校 --> 属性</span> school = <span>"</span><span>Jld</span><span>"</span> <span>def</span> <span>__init__</span>(self, name, sex, age): <span>#</span><span> 参数:obj1, "张三", "female", 84</span> <span>print</span>(self.<span>__dict__</span><span>) </span><span>#</span><span> 给对象添加新的属性</span> self.name = name <span>#</span><span> stu1.name = "张三"</span> self.sex = sex <span>#</span><span> stu1.sex = "female"</span> self.age = age <span>#</span><span> stu1.age = 84</span> <span>print</span>(self.<span>__dict__</span><span>) </span><span>#</span><span> 技能 ---> 方法</span> <span>def</span><span> learn(self): </span><span>print</span>(<span>"</span><span>learning...</span><span>"</span><span>) </span><span><span># obj1 = Student() </span> <span># Student(obj1) ---> __init__(self) ---> self==obj1</span></span><span> #</span><span> obj2 = Student() # Student(obj2) ---> __init__(self) ---> self==obj2</span><span> #</span><span> obj3 = Student() # Student(obj3) ---> __init__(self) ---> self==obj3</span> </span><br><br><span style="font-family:"> <span>#</span><span> 给对象添加独有的属性:</span><span> #</span><span> 第一种方法(很麻烦):调用类后,为对象传入对象独有的特征(属性)</span> obj1.name = <span>"</span><span>张三</span><span>"</span><span> obj1.sex </span>= <span>"</span><span>female</span><span>"</span><span> obj1.age </span>= 84 <span>#</span><span> 第二种方法:调用类时,为对象传入对象独有的特征(属性)</span><span> #</span><span> __init__(self, name, sex, age):obj1 --> self "张三" --> name "female" --> sex 84 --> age</span><span> #</span><span> 调用类时:会将对象当做第一个参数,并与括号内所有的参数一并传给__init__()</span> obj1 = Student(<span>"</span><span>张三</span><span>"</span>, <span>"</span><span>female</span><span>"</span>, 84)</span>
执行结果:
<span style="font-family:"><span>{} {</span><span>"</span><span>name</span><span>"</span>: <span>"</span><span>张三</span><span>"</span>, <span>"</span><span>sex</span><span>"</span>: <span>"</span><span>female</span><span>"</span>, <span>"</span><span>age</span><span>"</span>: 84}</span>
注意:凡是在类内部定义的.__或者__结尾的方法都有特殊意义
__init__():在类内部定义的方法,在调用类时触发,会自动将对象当做第一个参数自动传入并执行
3、对象名字的查找顺序
对象名字的查找顺序:
① 对象.属性,会先找对象自己的
② 若对象没有,会去找类的
③ 对象没有,类也没有,就会报错
定义一个类:
<span style="font-family:"><span>class</span><span> people: country </span>= <span>"</span><span>China</span><span>"</span><span> name </span>= <span>"</span><span>李四</span><span>"</span> <span>def</span> <span>__init__</span><span>(self, name, sex, age): self.name </span>=<span> name self.sex </span>=<span> sex self.age </span>=<span> age </span><span>def</span><span> run(self): </span><span>print</span>(<span>"</span><span>running...</span><span>"</span><span>) obj1 </span>= people(<span>"</span><span>张三</span><span>"</span>, <span>"</span><span>female</span><span>"</span>, 95<span>) </span><span>print</span>(obj1.name) <span>#</span><span> 张三 找对象自己的name属性</span> <span>print</span>(obj1.country) <span>#</span><span> China 对象没有,找类中的属性</span><span> #</span><span> 报错:AttributeError: "people" object has no attribute "json"</span> <span>print</span>(obj1.json) <span>#</span><span> 对象没有,类也没有,就报错</span></span>
4、一切皆对象
在python中一切皆对象
比如:python的八大数据类型都是类
定义数据类型时,内部会自动调用相应的类,然后产生对象
<span style="font-family:"><span>"""</span><span> 在python中一切皆对象 </span><span>"""</span> <span>class</span><span> foo: </span><span>def</span> <span>__init__</span><span>(self, x, y, z): self.x </span>=<span> x self.y </span>=<span> y self.z </span>=<span> z </span><span>#</span><span> 产生对象</span><span> #</span><span> 调用类产生对象的过程称之为类的实例化,对象称之为一个类的实例</span> <span> foo_obj </span>= foo(10, 20, 30<span>) </span><span>print</span><span>(foo_obj) </span><span>#</span><span> 查看 字符串 类型</span> <span>print</span>(type(str)) <span>#</span><span> <class "type"></span><span> #</span><span> 查看 列表 类型</span> <span>print</span>(type(list)) <span>#</span><span> <class "type"></span><span> #</span><span> 查看 字典 类型</span> <span>print</span>(type(dict)) <span>#</span><span> <class "type"></span><span> #</span><span> 查看 元组 类型</span> <span>print</span>(type(tuple)) <span>#</span><span> <class "type"></span><span> #</span><span> 查看 浮点型 类型</span> <span>print</span>(type(float)) <span>#</span><span> <class "type"></span><span> #</span><span> 查看 整型 类型</span> <span>print</span>(type(int)) <span>#</span><span> <class "type"></span><span> #</span><span> 查看 布尔值 类型</span> <span>print</span>(type(bool)) <span>#</span><span> <class "type"></span> <span>#</span><span> 除了这些还有很多都是类,既然是类,就可以是对象,所以在python中一切皆对象</span></span>
执行结果:
<span style="font-family:"><<span>__main__</span>.foo object at 0x0000014471D71C88> <<span>class</span> <span>"</span><span>type</span><span>"</span>> <<span>class</span> <span>"</span><span>type</span><span>"</span>> <<span>class</span> <span>"</span><span>type</span><span>"</span>> <<span>class</span> <span>"</span><span>type</span><span>"</span>> <<span>class</span> <span>"</span><span>type</span><span>"</span>> <<span>class</span> <span>"</span><span>type</span><span>"</span>> <<span>class</span> <span>"</span><span>type</span><span>"</span>></span>
四、根据面向对象编程编写一个“人狗大作战”例子
<span style="font-family:"><span>"""</span><span> 需求:有一个人对象,狗对象,狗咬人,人打狗 - 对象人1 - 特征 - 生命:1000 - 名字:name = "张三" - 攻击力:arg - 技能 - 打:hit - 对象人2 - 特征 - 生命:950 - 名字:name = "李四" - 攻击力:arg - 技能 - 打:hit - 抽象出类 - 人类: - 相同特征 - 生命 - 相同特征 - 打 - 狗对象1 - 特征 - 生命值:150 - 名字:name = "二哈" - 品种:dog_type = "哈士奇" - 攻击力:arg - 技能 - 咬:bite - 狗对象2 - 特征 - 生命值:250 - 名字:name = "小短腿" - 品种:dog_type = "柯基" - 攻击力:arg - 技能 - 咬:bite - 抽象出类 - 狗类: - 相同特征 - 生命 - 相同特征 - 咬 </span><span>"""</span> <span>import</span><span> time </span><span>#</span><span> 人类</span> <span>class</span><span> People: </span><span>def</span> <span>__init__</span><span>(self, name, life, arg): self.name </span>=<span> name self.life </span>=<span> life self.arg </span>=<span> arg </span><span>#</span><span> 人对象调用hit时,传入狗对象</span> <span>def</span><span> hit(self, dog_obj): </span><span>print</span>(f<span>"</span><span>[{self.name}]要开始打[{dog_obj.name}]了</span><span>"</span><span>) </span><span>#</span><span> 减掉狗对象的生命值 值为人对象的攻击力</span> dog_obj.life -=<span> self.arg </span><span>print</span>(f<span>"</span><span>[{dog_obj.name}]的生命值减掉:[{self.arg}],剩余血量为:[{dog_obj.life}]</span><span>"</span><span>) </span><span>if</span> dog_obj.life <=<span> 0: </span><span>print</span>(f<span>"</span><span>[{dog_obj.name}]已经没了</span><span>"</span><span>) </span><span>return</span><span> True </span><span>#</span><span> 狗类</span> <span>class</span><span> Dogs: </span><span>def</span> <span>__init__</span><span>(self, name, life, dog_type, arg): self.name </span>=<span> name self.life </span>=<span> life self.dog_type </span>=<span> dog_type self.arg </span>=<span> arg </span><span>#</span><span> 狗对象调用bite时,传入人对象</span> <span>def</span><span> bite(self, p_obj): </span><span>print</span>(f<span>"</span><span>[{self.name}]要开始咬[{p_obj.name}]了</span><span>"</span><span>) </span><span>#</span><span> 减掉人对象的生命值 值为狗对象的攻击力</span> p_obj.life -=<span> self.arg </span><span>print</span>(f<span>"</span><span>[{p_obj.name}]的生命值减掉:[{self.arg}],剩余血量为:[{p_obj.life}]</span><span>"</span><span>) </span><span>if</span> p_obj.life <=<span> 0: </span><span>print</span>(f<span>"</span><span>[{p_obj.name}]已经没了</span><span>"</span><span>) </span><span>return</span><span> True p1 </span>= People(<span>"</span><span>张三</span><span>"</span>, 1000, 50<span>) <span># 人对象</span> d1 </span>= Dogs(<span>"</span><span>二哈</span><span>"</span>, 150, <span>"</span><span>哈士奇</span><span>"</span>, 200<span>) <span># 狗对象 </span></span><span>while</span><span> True: </span><span>#</span><span> 开始狗咬人,人打狗</span> res1 =<span> d1.bite(p1) </span><span>if</span><span> res1: </span><span>break</span><span> time.sleep(</span>1) <span>#</span><span> 休眠1秒</span> <span> res2 </span>=<span> p1.hit(d1) </span><span>if</span><span> res2: </span><span>break</span><span> time.sleep(</span>1) <span>#</span><span> 休眠1秒</span></span>
执行结果:
<span style="font-family:"><span>[二哈]要开始咬[张三]了 [张三]的生命值减掉:[</span>200],剩余血量为:[800<span>] [张三]要开始打[二哈]了 [二哈]的生命值减掉:[</span>50],剩余血量为:[100<span>] [二哈]要开始咬[张三]了 [张三]的生命值减掉:[</span>200],剩余血量为:[600<span>] [张三]要开始打[二哈]了 [二哈]的生命值减掉:[</span>50],剩余血量为:[50<span>] [二哈]要开始咬[张三]了 [张三]的生命值减掉:[</span>200],剩余血量为:[400<span>] [张三]要开始打[二哈]了 [二哈]的生命值减掉:[</span>50<span>],剩余血量为:[0] [二哈]已经没了</span></span>
五、面向对象总结
面向对象:
核心是“对象”,对象指的是特征与技能的结合体
基于该编程思想编写程序,就好比在创造世界,一种上帝式的思维方式
优点:
可扩展性强
缺点:
编写复杂难度较面向过程高
1、类的实例化:调用类的过程称之为类的实例化,产生的对象也可以称之为类的一个实例
调用类产生对象发生的事情:
① 会产生一个空对象的名称空间
② 会自动触发__init__,并且会将对象当做第一个参数传入
③ 会将调用类括号内的参数一并传给__init__()
<span style="font-family:"><span><span># 定义一个类</span><br>class</span><span> People: national </span>= <span>"</span><span>han</span><span>"</span> <span>def</span> <span>__init__</span><span>(self, name, age, sex): self.name </span>=<span> name self.age </span>=<span> age self.sex </span>=<span> sex </span><span>#</span><span> 注意:看到self就应该知道是对象本身,在这里就是下面代码中的p_obj对象</span> <span>def</span><span> learn(self): </span><span>print</span>(<span>"</span><span>learning...</span><span>"</span><span>) p_obj </span>= People(<span>"</span><span>张三</span><span>"</span>, 184, <span>"</span><span>female</span><span>"</span><span>) </span><span>print</span>(p_obj.name, p_obj.age, p_obj.sex)</span>
执行结果:
<span style="font-family:">张三 184 female</span>
2、查看类与对象的名称空间:类.__dict__ 对象.__dict__
<span style="font-family:"><span><span># 使用上面People类执行下列代码</span><br><br>print</span>(People.<span>__dict__</span><span>) <span># 查看类的名称空间 </span></span><span>print</span>(p_obj.<span>__dict__</span>) <span># 查看对象的名称空间</span></span>
执行结果:
<span style="font-family:">{<span>"</span><span>__module__</span><span>"</span>: <span>"</span><span>__main__</span><span>"</span>, <span>"</span><span>national</span><span>"</span>: <span>"</span><span>han</span><span>"</span>, <span>"</span><span>__init__</span><span>"</span>: <function People.<span>__init__</span> at 0x000001B4D9BC96A8>, <span>"</span><span>learn</span><span>"</span>: <function People.learn at 0x000001B4D9BC9620>, <span>"</span><span>__dict__</span><span>"</span>: <attribute <span>"</span><span>__dict__</span><span>"</span> of <span>"</span><span>People</span><span>"</span> objects>, <span>"</span><span>__weakref__</span><span>"</span>: <attribute <span>"</span><span>__weakref__</span><span>"</span> of <span>"</span><span>People</span><span>"</span> objects>, <span>"</span><span>__doc__</span><span>"</span><span>: None} {</span><span>"</span><span>name</span><span>"</span>: <span>"</span><span>张三</span><span>"</span>, <span>"</span><span>age</span><span>"</span>: 184, <span>"</span><span>sex</span><span>"</span>: <span>"</span><span>female</span><span>"</span>}</span>
3、类或对象的属性操作:增、删、查、改
<span style="font-family:"><span>#</span><span> 使用上面People类执行下列代码</span> <span>#</span><span> 类的属性操作</span> People.sal = 3000 <span>#</span><span> 增</span> People.number = 1 <span>#</span><span> 增</span> <span>del</span> People.number <span>#</span><span> 删</span> People.sal = 4500 <span>#</span><span> 改</span> <span>print</span>(People.sal) <span>#</span><span> 查</span> <span>#</span><span> 对象的属性操作</span> p_obj.county = <span>"</span><span>China</span><span>"</span> <span>#</span><span> 增</span> <span>del</span> p_obj.sex <span>#</span><span> 删</span> p_obj.name = <span>"</span><span>李四</span><span>"</span> <span>#</span><span> 改</span> <span>print</span>(p_obj.name) <span>#</span><span> 查</span></span>
执行结果:
<span style="font-family:">4500<span> 李四</span></span>
4、类中数据属性(类中的变量):类中的属性是给对象使用的,对象引用类中的属性,指向的都是类中同一个内存地址
<span style="font-family:"><span>#</span><span> 使用上面People类执行下列代码</span> <span> p_obj1 </span>= People(<span>"</span><span>王五</span><span>"</span>, 84, <span>"</span><span>female</span><span>"</span><span>) p_obj2 </span>= People(<span>"</span><span>赵六</span><span>"</span>, 85, <span>"</span><span>male</span><span>"</span><span>) p_obj3 </span>= People(<span>"</span><span>孙七</span><span>"</span>, 86, <span>"</span><span>female</span><span>"</span><span>) </span><span>print</span><span>(p_obj1.national, id(p_obj1)) </span><span>print</span><span>(p_obj2.national, id(p_obj2)) </span><span>print</span>(p_obj3.national, id(p_obj3))</span>
执行结果:
<span style="font-family:">han 2612115777632<span> han </span>2612115777744<span> han </span>2612115777800</span>
5、类中的方法(类中的函数):类中的方法是给对象使用的,由对象来调用就会将方法绑定给不同的对象,并且会将对象当做第一个对象传入
<span style="font-family:"><span>#</span><span> 使用上面People类执行下列代码</span> <span> p_obj1 </span>= People(<span>"</span><span>王五</span><span>"</span>, 84, <span>"</span><span>female</span><span>"</span><span>) p_obj2 </span>= People(<span>"</span><span>赵六</span><span>"</span>, 85, <span>"</span><span>male</span><span>"</span><span>) p_obj3 </span>= People(<span>"</span><span>孙七</span><span>"</span>, 86, <span>"</span><span>female</span><span>"</span><span>) </span><span>print</span><span>(People.learn) </span><span>print</span><span>(p_obj1.learn) </span><span>print</span><span>(p_obj2.learn) </span><span>print</span>(p_obj3.learn)</span>
执行结果:
<span style="font-family:"><function People.learn at 0x0000022590CA9620> <bound method People.learn of <<span>__main__</span>.People object at 0x0000022590CBA860>> <bound method People.learn of <<span>__main__</span>.People object at 0x0000022590CBA8D0>> <bound method People.learn of <<span>__main__</span>.People object at 0x0000022590CBA908>></span>
6、对象属性的查找顺序:先从对象自己的名称空间找 —> 类的名称空间查找
<span style="font-family:"><span>#</span><span> 使用上面People类执行下列代码</span> <span>print</span>(p_obj1.national) <span>#</span><span> 从类中查找</span> <span>print</span>(p_obj1.national2) <span>#</span><span> 类中也没有,报错</span></span>
7、对象绑定方法的特殊之处
① 会将对象当做第一个参数传入
② 若对象的绑定发放中还有其他参数,会一并传入。
8、一切皆对象:在python3中,类即类型
<span style="font-family:"><span>#</span><span> 使用上面People类执行下列代码</span> <span>print</span>(type(p_obj)) <span>#</span><span> <class "__main__.People"></span> str1 = <span>"</span><span>orange</span><span>"</span> <span>print</span>(type(str1)) <span>#</span><span> <class "str"></span> list1 = [1, 2, 3<span>] </span><span>print</span>(type(list1)) <span>#</span><span> <class "list"></span></span>
执行结果:
<span style="font-family:"><<span>class</span> <span>"</span><span>__main__.People</span><span>"</span>> <<span>class</span> <span>"</span><span>str</span><span>"</span>> <<span>class</span> <span>"</span><span>list</span><span>"</span>></span>