面向对象
1.面向对象的定义
1.1什么是面向对象?
面向对象是一门编程思想。
1.2面向过程的编程思想:
-核心是'过程'二字,过程指的是解决问题的步骤,即现做什么后做什么?基于该编程思想来编写程序,就好比在设计一条工厂的流水线,一种机械的思维方式。
-优点:将复杂的问题流程化,进而简单化。
-缺点:其一发而动全身,程序的可扩展性差。
注意:编程思想仅仅是一门思想,与任何技术没有关系。
1.3面向对象的编程思想:
注意:要将自己当作一个上帝。
核心是“对象”二字,对象指的是“特征与技能”的结合体。
基于该编程思想编写程序,就好比在创造世界,一种上帝式的思维方式。
-优点:可扩展性高
-缺点:编写程序的复杂程度比面向过程高
1.4如何产生对象?
1.41什么是类?
类指的是类型、类别
1.42 在 两种角度去看待:
-现实世界中:
-先有一个个对象,经过社会文明的发展,随之总结出类
对象是实际存在的,而类抽象产生的
-在程序:
-必须现有类,再通过“调用类,产生对象”
1.5如何定义类:
-如何写类,并产生对象:
-先从现实的世界中通过一个个对象总结出类;
-然后在定义类,后调用类产生对象
比如选课系统:
-选课的学生类
-学生对象一:
特征:
-姓名:王一
-性别:male
-年龄:26
-学校:oldboy
技能:
-技术:python
-学习:learn
-选课:course
-学生对象二:
特征:
-姓名:张三
-性别:male
-年龄:29
-学校:oldboy
技能:
-技术:python
-学习:learn
-选课:course
1.6定义类的语法:
class:关键字:帮助你产生类。
class类的名字:
类一些列对象相同的特征与技能的结合体
-对象之间的相同的特征:
-学校
school = 'oldboy'
-对象之间相同的技能:
-python
def python():
pass
-learn
def learn()"
pass
-course
def course():
pass
## 2.class 类名
class 类名:
特征
技能
-定义类名的规范:
-驼峰命名法
def foo():函数名指的是函数的内存地址
print(foo) # <function foo at 0x000001CDFF119048>
# 定义老男孩学生类
class OldboyStudent: # 类名指向的是类的内存地址
# 学生相同的特征
# 在类中的特征 也称之为 “属性” attribute
school = 'oldboy'
# 学生相同的技能
# 注意: 在类内部定义函数,会默认有一个参数self
def learn(self): # self此时当做一个形参
print('learning....')
print(OldboyStudent) # <class '__main__.OldboyStudent'>
#查看名称空间
类.__dict__ 对象.__dict__
class OldboyStudent():
school = 'oldboy'
def learn(self):
print('from the world')
print(OldboyStudent)
print(OldboyStudent.__dict__)
print(OldboyStudent.__dict__['school'])
print(OldboyStudent.__dict__['learn'])
OldboyStudent.__dict__['learn'](123)
>>>>>>>>>>>>
<class '__main__.OldboyStudent'>#####类的函数对象
{'__module__': '__main__', 'school': 'oldboy', 'learn': <function OldboyStudent.learn at 0x000001F80EC20158>, '__dict__': <attribute '__dict__' of 'OldboyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'OldboyStudent' objects>, '__doc__': None}######这个类的名称空间
oldboy ######这个是school的打印结果
<function OldboyStudent.learn at 0x000001F80EC20158>######这个函数的learn的内存地址
from the world ######这个是给函数传参得到的一个打印结果
class OldboyStudent():
school = 'oldboy'
def learn(self):
print('from the world')
p = OldboyStudent
# print(OldboyStudent)
# 类提供一种特殊获取名字的方式 “类名.名字” 的方式
#查
print(p.school)
#改
p.school = 'oldgirl'
print(p.school)
#删
>>>>>>>>>>>>>
oldboy
oldgirl
#删
del p.school
print(p.school)
>>>>>>>>>>
Traceback (most recent call last):
File "E:/working/111.py", line 61, in <module>
print(p.school)
AttributeError: type object 'OldboyStudent' has no attribute 'school'
######删除了 再去打印 会报错
#增
p.new_student = 'david'
print(p.new_student)
>>>>>>>>>>
david
重点
-函数的名称空间:
在函数调用时产生,函数调用结束后销毁
-类的名称空间:
在定义阶段,会将类中的所有的名字,仍进类的名称空间中。
3.对象的调用
-调用类产生对象
类名+()调用类产生的对象
类的名称空间在定义时产生,对象的名称空间在调用时产生。
调用类产生的对象的过程称之为类的实例化,对象称之为类的一个实例
class Student:
school = 'oldboy'#特征
def learn(self): #这个是技能 函数就是方法
print(self)
print('from the world')
Student.learn(123)####打印的是结果
>>>>>>>>>>
123
from the world
class Student:
school = 'oldboy'#特征
def learn(self): #这个是技能 函数就是方法
print(self)
print('from the world')
stu1 = Student()#####调用类产生的对象
stu2 = Student()#####调用类产生的对象
print(stu1)
print(stu1.school)
print(stu1.learn)
print('='*50)
print(stu2)
print(stu2.school)
print(stu2.learn)
>>>>>>>>>>>>>>>>>>>>>>>>>>
<__main__.Student object at 0x0000020A3B6AECF8> ###这个是类的对象地址
oldboy #####打印的结果
<bound method Student.learn of <__main__.Student object at 0x0000020A3B6AECF8>>######这个是打印的是一种方法
==================================================
<__main__.Student object at 0x0000020A3B6AEE48>
oldboy
<bound method Student.learn of <__main__.Student object at 0x0000020A3B6AEE48>>
####综上类产生的2个对象 内存地址是不一样的
4.对象的绑定
由对象来调用类内部的函数,称之为对象的绑定方法
1.会将对象当做第一个参数传入。******
2.若对象的绑定方法中还有其他参数,会一并传入。
class Student:
school = 'oldboy'
def learn(self):
print(self)
print('from the world')
stu1 = Student() ###得到一个对象
stu1.name = 'david'
stu1.sex = 'male'
stu1.age = 20
print(stu1.name,stu1.sex,stu1.age)
>>>>>>>>>>>>>>>
david male 20
注意:
想要在调用类时,为对象传入对象独有的特征:
__init__(self, name, sex, age): # name---> tank , sex---> male, age----> 17
调用类发生的事情:此时会产生一个对象 obj = Foo(david,20)
1.产生一个空对象的名称空间
2.自动触发内容__init__方法的执行
3会将对象本身当作第一个参数,以及调用括号内的所有参数并传给__init__
调用时,会将对象当作第一个参数,与括号内的所有参数一并传入__init__ ()
-凡是在类内部定义的--开头或者结尾的方法都有特殊的意义
在类内部的定义方法:在调用类时触发,会将对象当作第一个参数,与括号内的所有参数一并传入__init__ ()
class Student:
school = 'oldboy'
def __init__(self,name,sex,age):#####name ==david age == 20 sex ==male
self.name = name ###把形参的的具体值,赋值给对象self的属性变量name,这个name可以是任意的,可以是my_name 也可以是self.my_name = name 打印出来的结果是要这么打印 print(stu1.my_name) 下面的age sex同理
self.sex = sex
self.age = age
def learn(self):
print(self)
print('from the world')
stu1 = Student('david','male',20)
print(stu1.name)
print(stu1.sex)
print(stu1.age)
>>>>>>>>>>>>>
david
male
20
5.对象名称空间的查找顺序
1.对象的属性,会先去找对象自己的;
2.若对象没有,回去找类的;
3.若类没有,则会报错。
class People:
school = 'oldboy'
def __init__(self,name, sex, age):
self.name = name
self.sex = sex
self.age = age
def learn(self):
print('from the world')
p_obj = People('david','male',20)
print(p_obj.name)####找自己属性的name
print(p_obj.school) ######自己的属性没有,去类中寻找
# print(p_obj.jason)
print(p_obj.__dict__) #####这个是内存地址
p_obj.school = '中国'
print(p_obj.__dict__)######内存地址中包括了'school': '中国'
print(People.__dict__)######'school': 'oldboy'
print(p_obj.school)
>>>>>>>>>>>>>>>>>>>
david
oldboy
{'name': 'david', 'sex': 'male', 'age': 20}
{'name': 'david', 'sex': 'male', 'age': 20, 'school': '中国'}
{'__module__': '__main__', 'school': 'oldboy', '__init__': <function People.__init__ at 0x000002096C710268>, 'learn': <function People.learn at 0x000002096C7101E0>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
中国
6.在python中一切皆是对象
# l1 ---> list对象
# l1 = list([1, 2, 3])
# dict()
# tuple((1, 2, 3))
# float
# str
# set
# bool
# enumerate
# bytes
# filter
以上的举例说明 一切皆是对象
python3中,8大数据类型都是类
定义数据类型的值时,内部自动调用响应的类,然后产生对象
# 4.类中数据属性(类中的变量): 类中属性是给对象使用的,对象引用类中的属性,指向的都是类中同一个内存地址。
# 5.类中的方法(类中的函数): 类中的方法是给对象使用的,
# 由不同的对象来调用就会将方法绑定给不同的对象, 并且会将对象当做第一个参数传入
# 6.对象属性的查找顺序: 先从对象自己名称空间中查找 ---》 类的名称空间中查找
# 7.对象绑定方法的特殊之处:
''
类内部的函数
1.由对象来调用,会将对象当做第一个参数传入。******
2.若对象的绑定方法中还有其他参数,会一并传入。
3.由类来调用,就是一个普通的函数,函数需要几个参数,就传入几个参数
#人狗大战
class People:
def __init__(self,name,life, arg):
self.name = name
self.life = life
self.arg = arg
def bite(self,dog_obj):
print(f'人{self.name}开始咬狗{dog_obj.name}')
if dog_obj.life <= 0:
print('狗已经挂了')
return True
else:
dog_obj.life -= self.arg
print(f'狗的生命值减掉{self.arg},还剩余狗的血量是{dog_obj.life}')
class Dog:
def __init__(self,name, life, dog_type,arg):
self.name = name
self.life = life
self.dog_type = dog_type
self.arg = arg
def bite(self,p_obj):
print(f'狗{self.name}开始咬人了{p_obj.name}')
if p_obj.life <= 0:
print('人已经挂了')
return True
else:
p_obj.life -= self.arg
print(f'人的生命值减掉{self.arg},还剩余人的血量是{p_obj.life}')
p1 = People('aa',3000,1000)
d1 = Dog('bb',6000,'哈士奇',1000)
while True:
res1 = d1.bite(p1)
if res1:
break
res2 = p1.bite(d1)
if res2:
break
>>>>>>>>>>>>>>>>>>>
狗bb开始咬人了aa
人的生命值减掉1000,还剩余人的血量是2000
人aa开始咬狗bb
狗的生命值减掉1000,还剩余狗的血量是5000
狗bb开始咬人了aa
人的生命值减掉1000,还剩余人的血量是1000
人aa开始咬狗bb
狗的生命值减掉1000,还剩余狗的血量是4000
狗bb开始咬人了aa
人的生命值减掉1000,还剩余人的血量是0
人aa开始咬狗bb
狗的生命值减掉1000,还剩余狗的血量是3000
狗bb开始咬人了aa
人已经挂了
#人狗大战
class People:
def __init__(self,name,life, arg):
self.name = name
self.life = life
self.arg = arg
def bite(self,dog_obj):
print(f'人{self.name}开始咬狗{dog_obj.name}')
if dog_obj.life <= 0:
print('狗已经挂了')
return True
else:
dog_obj.life -= self.arg
print(f'狗的生命值减掉{self.arg},还剩余狗的血量是{dog_obj.life}')
class Dog:
def __init__(self,name, life, dog_type,arg):
self.name = name
self.life = life
self.dog_type = dog_type
self.arg = arg
def bite(self,p_obj):
print(f'狗{self.name}开始咬人了{p_obj.name}')
if p_obj.life <= 0:
print('人已经挂了')
return True
else:
p_obj.life -= self.arg
print(f'人的生命值减掉{self.arg},还剩余人的血量是{p_obj.life}')
p1 = People('aa',3000,1000)
d1 = Dog('bb',6000,'哈士奇',1000)
lag = True
while flag:
res2 = p1.bite(d1)
if res2:
flag = False
>>>>>>>>>>>>>>>>>>>>>>>
人aa开始咬狗bb
狗的生命值减掉1000,还剩余狗的血量是5000
人aa开始咬狗bb
狗的生命值减掉1000,还剩余狗的血量是4000
人aa开始咬狗bb
狗的生命值减掉1000,还剩余狗的血量是3000
人aa开始咬狗bb
狗的生命值减掉1000,还剩余狗的血量是2000
人aa开始咬狗bb
狗的生命值减掉1000,还剩余狗的血量是1000
人aa开始咬狗bb
狗的生命值减掉1000,还剩余狗的血量是0
人aa开始咬狗bb
狗已经挂了