面向过程&面向对象
面向过程:核心是过程二字,过程指的是解决问题的步骤,设计一条流水线,机械式的思维方式
- 优点:复杂的问题流程化,进而简单化
- 缺点:可扩展性差
面向对象:核心就是对象二字,对象就是特征与技能的结合体
- 优点:可扩展性强
- 缺点:编程复杂度高
- 应用场景:用户需求经常变化,互联网应用,游戏,企业内部应用
类&对象
对象:对象就是特征与技能的结合体
类:就是一系列对象相似的特征与技能的结合体
- 现实世界中:一定先有对象,后有类
- 程序中:一定得先定义类,后调用类来产生对象
创建类
Python中的类用class关键字定义,特征用变量标识,方法用函数标识
class Student:
school = "UCAS" # 特征属性,用变量表示
def learn(self): # 方法属性,用函数表示
print("is learning......")
def sleep(self):
print("is sleeping......")
- 注意类名在书写上用大驼峰体,每个英文字母首字母大写
- 类的属性:特征属性和方法属性,通过__dict__或者点的方式访问操作(增删改查)
- 使用类可以将数据与操作数据的方法结合在一起
print(Student.__dict__)
print(Student.__dict__["school"])
print(Student.school)
print(Student.__dict__["learn"])
print(Student.learn) # 返回命名空间
实例化对象
# 实例化对象,即类的调用
stu1 = Student()
stu2 = Student()
stu3 = Student()
print(stu1, id(stu1)) # 返回对象的命名空间和id,每个对象的命名空间不同,id也不同
print(stu2, id(stu2))
print(stu3, id(stu3))print(stu1.__dict__)
# 返回空,似乎对象没有属性,但是对象肯定是有school/learn等属性的呀print(stu2.__dict__)
print(stu3.__dict__)
print(stu1.school, stu1.learn) # 返回结果表明,对象的确是有school/learn等属性的print(stu2.school, stu2.learn)
print(stu3.school, stu3.learn)
- 这其实是因为:对象使用dict只能查看对象自己特有的属性,特性
- 而此时这种方式实例化出来的三个对象没有自己特有的属性,仅有共同的属性(即类的属性)。
- 所以,__dict__查看的结果为空。
- 但是值得注意的是,此时每个对象依然是不同的,因为每个对象的命名空间不同,id也不同
__init__函数
那如何为每个对象定制私有属性呢,即自己的特性,不如不同的名字和年龄等
修改类为:
class Student:
school = "UCAS" # 特征属性,用变量表示
def __init__(self, name, sex, age):
self.Name = name
self.Sex = sex
self.Age = age
def learn(self): # 方法属性,用函数表示
print("%s is learning......" % self.Name)
def sleep(self):
print("is sleeping......")
实例化对象的同时传入私有特征参数:
#在实例化对象
stu1 = Student("小明", "男", 18)
stu2 = Student("小强", "男", 20)
stu3 = Student("小兰", "女", 19)
"""
print(stu1.__dict__) # 返回{'Name': '小明', 'Sex': '男', 'Age': 18}
print(stu2.__dict__) # 返回{'Name': '小强', 'Sex': '男', 'Age': 20}
print(stu3.__dict__) # 返回{'Name': '小兰', 'Sex': '女', 'Age': 19}
可以看到此时实例化之后,每个对象使用dict都能看到自己的特有属性
加上__init__方法后,实例化的步骤:
- 1、先产生一个空对象stu1
- 2、Student.__init__(stu1,'小明','男',18) 次步骤程序自动调用__init__函数
这时,每个对象都既有私有特征,又有共有特征
其中,对象的公有特征存放在类中,对象的私有特征存放在对象中
绑定方法
Student.learn(stu1) # f返回 小明 is learning......
stu1.learn() # f返回 小明 is learning......
Student.learn(stu2) # f返回 小强 is learning......
stu2.learn() # f返回 小强 is learning......
方法是绑定给对象使用的,绑定到不同的对象是不同的绑定方法
类中定义的方法(函数),就是为对象定义的
使用Student.learn(stu1) 过于麻烦,不如直接使用 stu1.learn()
- 绑定到对象的方法的特殊之处在于,绑定给谁就由谁来调用,
- 谁来调用,就会将‘谁’本身当做第一个参数传给方法,即自动传值(方法__init__也是一样的道理)
- 注意:绑定到对象的方法的这种自动传值的特征,决定了在类中定义的函数都要默认写一个参数self,
- self可以是任意名字,但是约定俗成地写出self
- 类的特征属性是绑定给对象使用的,obj.method称为绑定方法,内存地址都不一样
- ps:id是python的实现机制,并不能真实反映内存地址,如果有内存地址,还是以内存地址为准
属性查找
类有两种属性:特征属性和方法属性
- 类的特征属性是所有对象共享的
- 类的方法属性是绑定给对象用的,称为绑定到对象的方法
查找对象属性时:
- 对象现在自己的名称空间里找,
- 找不到则去类中找,
- 类也找不到就找父类...
- 最后都找不到就抛出异常
特征属性的增删改查
-
类可以直接操作类中的特征属性
Student.school = "MIT" #改 print(Student.school) #查 del Student.school #删 Student.country = "CN" #增
-
类不可以操作对象私有的特征属性
print(Student.Name) #报错
-
对象可以操作类中的特征属性,修改后,成为自己的特性,可通过__dict__找到
print(stu1.__dict__) # 返回 {'Name': '小明', 'Sex': '男', 'Age': 18} print(stu1.school) # 返回 UCAS stu1.school = "MIT" print(stu1.school) # 返回 MIT print(stu1.__dict__) # 返回 {'Name': '小明', 'Sex': '男', 'Age': 18, 'school': 'MIT'} print(Student.school) # 返回 UCAS print(stu2.school) # 返回 UCAS
对象可以访问类中的特征属性
对象的私有特征属性与类中定义的公有特征属性相同时,对象优先使用自己私有的特征属性
对象1的school改成“MIT",不影响类和其他对象的school值