06_01、面向对象编程
类扩展
读懂python中的self
一、面向过程的编程

1 面向过程的核心是:过程二字,即先干什么,在干什么, 最后干什么。机械式思维方式 2 3 # 面向过程不是一门技术,是一种做事的思维方式 4 eg: 5 大象放冰箱的步骤: 6 1. 打开冰箱门, 7 2. 把大象放进冰箱 8 3. 观赏冰箱门 9 10 优点:复杂的问题简单化,流程化 11 缺点:扩展性差,牵一发而动全身 12 应用场景:对扩展性要求不高的地方 13 eg2: 14 写一个注册功能 15 # 用户注册 16 17 # 1、与用户交互获取用户名和密码 18 def interactive(): 19 username = input('username:').strip() 20 password = input('password:').strip() 21 return { 22 'username': username, 23 'password': password 24 } 25 26 27 # 2、验证参数 28 def check_info(param): 29 # 验证用户名密码,如果未填写,要求必须输入 30 flag = True 31 if len(param['username']) == 0: 32 print('username必须填写') 33 flag = False 34 if len(param['password']) == 0: 35 print('password必须填写') 36 flag = False 37 return { 38 'param': param, 39 'flag': flag 40 } 41 42 43 # 3、保存数据 44 def register(info): 45 if info['flag']: 46 with open('userinfo.txt', 'w', encoding='utf8') as f: 47 data = '%s|%s' % (info['param']['username'], info['param']['password']) 48 f.write(data) 49 50 51 def main(): 52 param = interactive() 53 info = check_info(param) 54 register(info) 55 56 57 main()
二、面向对象的编程
面向对象核心是:对象二字
# 在python中,一切皆对象
1. 在程序中:
对象就是盛放数据属性和功能的容器
2. 在现实生活中
对象就是特征与技能的结合体
优点:扩展性强
缺点:把所有问题,对象化,模块化
应用场景:对扩展性要求高的地方

1 def choose_course(stu_dic,course): 2 stu_dic['courses'].append(course) 3 print('%s选课成功%s' % (stu_dic['name'], stu_dic['courses'])) 4 5 stu1 = { 6 'name': 'tom', 7 'age': 19, 8 'gender': 'male', 9 'courses': [], 10 'choose_course':choose_course 11 } 12 13 stu2 = { 14 'name': 'kevin', 15 'age': 20, 16 'gender': 'male', 17 'courses': [], 18 'choose_course': choose_course 19 } 20 21 stu1['choose_course'](stu1, 'python') 22 stu2['choose_course'](stu2, 'python')
三、类的定义和对象的产生
1、类
在生活中,对象是特征与技能的结合体,所以站在不同的角度,对对象的分类也不一样。
所谓类:一系列对象相似的特征和相似的技能的结合体
2、先有类还是先有对象?
1. 现实生活中:
一定是先有对象,在有类
2. 程序中:
必须先定义类,再调用类产生对象
3、类的命名规范
类名,遵循变量的命名规范即可
类名一般都是首字母大写
若果有多个单词,推荐使用大驼峰
4、定义类属性和方法
class Student(): school = 'SH' # 类中给变量赋值:定义类属性 # 在类中,函数被称为是方法 def choose_course(stu_dic, course): stu_dic['courses'].append(course) print('%s选课成功%s' % (stu_dic['name'], stu_dic['courses'])) print(12233333)
5、定义类后发生的事情
1. 类定义完成后,会立马执行类体代码
2. 执行类体代码,把类中的名字都丢到类的名称空间去
3. 把类的名称空间绑定给__dict__, 查看方式是类名.__dict__
6、调用类,产生对象
stu1 = Student() # 调用类,得到一个空对象 stu2 = Student(参数) # 调用类,得到一个对象
7、查看对象的名称空间:对象名.__dict__
print(stu1.__dict__) # 空字典 print(stu2.__dict__) # 字典
四、定制对象独有的属性
class Student(): # 定义类属性 school = 'SH' # 初始化, 魔术方法 def __init__(stu_dic, name, age, gender, course=[]): stu_dic.name = name # stu.__dict__['name'] = 'tom' stu_dic.age = age # stu.__dict__['age'] = 19 stu_dic.gender = gender # stu.__dict__['gender'] = 'male' stu_dic.course = course # stu.__dict__['course'] = [] # 在类中,函数被称为是方法 def choose_course(stu_dic, course): stu_dic['courses'].append(course) print('%s选课成功%s' % (stu_dic['name'], stu_dic['courses'])) # Student() # stu = Student(stu, 'tom', 19, 'male') stu = Student('tom', 19, 'male') # 调用类的时候,会自动触发__init__方法,并且,会把对象自己当成第一个参数传给函数 stu1 = Student('kevin', 19, 'male') # 调用类的时候,会自动触发__init__方法,并且,会把对象自己当成第一个参数传给函数 # print(stu.__dict__) # print(stu1.__dict__) ''' 调用类的过程也称为是实例化的过程,得到的对象就是一个实例 '''
五、属性的查找顺序
1、类属性的读、改、删、增
# 读 print(Student.__dict__['school']) print(Student.school) # 改 Student.school = 'xxx' # 删除 # del Student.school # 增加 Student.aaa = 'xxx' print(Student.__dict__)
2、对象属性的增删改查
print(stu.name) print(stu.age) print(stu.gender) print(stu1.name) print(stu1.age) print(stu1.gender) # 对象的属性查找顺序: # 先在对象自己的名称空间中查找,如果找不到,去产生对象的类中取查找 print(stu.school) print(stu.__dict__['school']) # 只能在对象中查 # 增 stu.x = 'aaa' print(stu.__dict__) # 改 stu.x = 'bbb' # 删除 del stu.x
六、绑定方法
(一)绑定给对象的
类中定义的函数是类的函数属性,类可以使用,但必须遵循函数的参数规则,有几个参数需要传几个参数
但其实类中定义的函数主要是给对象使用的,而且是绑定给对象的,虽然所有对象指向的都是相同的功能,但是绑定到不同的对象就是不同的绑定方法,内存地址各不相同
绑定到对象的方法特殊之处在于,绑定给谁就应该由谁来调用,谁来调用,就会将’谁’本身当做第一个参数自动传入(方法__init__也是一样的道理)
绑定到不同对象的choose技能,虽然都是选课,但李建刚选的课,不会选给王大力,这正是”绑定“二字的精髓所在
# 绑定给对象的: class Student(): school = 'SH' def __init__(self, name, age): self.name = name self.age = age def tell_info(self, v): # 此时tell_info就是绑定给对象的方法 print('name:%s, age: %s, v:%s' % (self.name, self.age, v)) stu = Student('tom', 19) # 对象来调用方法:绑定给对象的方法由对象来调用,特殊之处在于把对象自己当成第一个参数传递到方法里面 stu.tell_info(10) # stu.tell_info(stu) # 注意:绑定给对象的方法,类也可以调用
(二)绑定给类的
# 绑定给类的: class Mysql(): def __init__(self, ip, port): self.ip = ip self.port = port # 绑定给类的方法 @classmethod def from_func(cls): # 通过cls和@classmethod装饰器写活类名 return cls('127.0.0.1', '3306') # 既绑定给类,又绑定给对象 def func(self): self.__class__ obj = Mysql('127.0.0.1', 3306) obj1 = obj.from_func() print(obj1) # 类的调用 Mysql.from_func() # Mysql.from_func(Mysql)
七、非绑定方法
1、非绑定方法的实现:
也叫 静态方法,即不绑定给类,也不绑定给对象
1. 加一个装饰器:@staticmethod
2. 函数已经变成普通函数,既没有self参数,也没有cls参数
3. 对象和类都可以调用
2、代码实现
class People(): def __init__(self, name, age): self.name = name self.age = age self.id = self.create_id() @staticmethod def create_id(): import uuid return uuid.uuid4() # 生成一串随机数 # 这项功能既不需要绑定给对象,也不需要绑定给类 obj = People('tom', 19) res=obj.create_id() # 对象调用,相当于obj.create_id(obj) print(People.create_id()) # 类调用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通