什么是对象

对象是由“数据”和“功能”组合而成,而编写程序的本质就是对数据的操作。在没有学“对象”之前,之前所编写的代码,数据和功能都是分开的。对象其实就是一个“容器”,容器内存放着数据和功能

  1. name = 'kevin'
  2. age = 22
  3. sex = 'male'
  4. def info():
  5. print('Name:%s Age:%s Sex:%s' % (name, age, sex))
  6. if __name__ == '__main__':
  7. info()
  8. # Name:kevin Age:22 Sex:male

什么是面向对象编程

面向对象编程就是造出很多个的对象,将原本分散开的相关数据与功能整合到一个个的对象里,既方便使用,也提高了程序的解耦合程度,从而提升了程序的可扩展性(需要强调的是,软件质量属性包含很多方面,面向对象解决的仅仅只是扩展性问题)

类与对象的创建

定义

用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例 ,在代码编程中是先有类才能有对象

语法

  1. class 类名:
  2. '类的帮助信息' #类文档字符串
  3. class_suite #类体代码 (存放功能和数据的地方)
  • class是定义类的关键字
  • 类名类似于函数名,推荐首字母大写
  • 类体代码就是数据、功能(数据:变量名 = 变量值,功能:函数)

使用

  1. class Student:
  2. name = 'kevin'
  3. age = 22
  4. gender = 'male'
  5. def info(self):
  6. print("个人信息")
  7. print(Student.name)
  8. # kevin
  9. print(Student.info)
  10. # <function Student.info at 0x7fb999bc86a8>
  11. """ 查看名称空间的方法:__dict__ """
  12. print(Student.__dict__) # 返回值是一个字典
  13. print(Student.__dict__['age']) # 获取类中的属性
  14. # 22
  15. print(Student.__dict__['info'])
  16. # <function Student.info at 0x7fec2a1c0510>
  17. """类名加括号就是产生一个对象"""
  18. obj_1 = Student()
  19. obj_2 = Student()
  20. print(obj_1.__dict__, obj_2.__dict__)
  21. # {} {}
  22. print(obj_1.name)
  23. # kevin
  24. print(obj_2.name)
  25. # kevin
  26. print(obj_1.info)
  27. # <bound method Student.info of <__main__.Student object at 0x7f86f1bc6518>>
  28. print(obj_2.info)
  29. # <bound method Student.info of <__main__.Student object at 0x7ff644cc6470>>
  30. Student.name = 'tony'
  31. print(obj_1.name) # Student.__dict__['name'] = tony 修改对应的值
  32. # tony
  33. print(obj_2.name)
  34. # tony

对象的实例化

将类产生对象的过程叫做对象的实例化

  1. class Student:
  2. def __init__(self, name, age, gender):
  3. self.name = name # obj.__dict__['name'] = name
  4. self.age = age # obj.__dict__['age'] = age
  5. self.gender = gender # obj.__dict__['gender'] = gender
  6. # 学生类公共的数据
  7. school = '清华大学'
  8. # 学生类公共的功能
  9. def choose_course(self):
  10. print('学生选课功能')
  11. obj_1 = Student('kevin', '22', 'male')
  12. print(obj_1.__dict__)
  13. # {'name': 'kevin', 'age': '22', 'gender': 'male'}
  14. obj_2 = Student('tony', '18', 'male')
  15. print(obj_2.__dict__)
  16. # {'name': 'tony', 'age': '18', 'gender': 'male'}

实例化一个对象总共发生了三件事:

  1. 在内存中开辟了一个对象空间
  2. 自动执行类中的 __init__ 方法,并将这个对象空间(内存地址)传给了 __init__ 方法的第一个位置参数 self
  3. __init__ 方法中通过 self 给对象空间添加属性

补充:

  • 针对括号内第一个形参self其实就是一个普通的变量名而已,只不过该变量名将来专门接收对象的,所以给它起了个固定的名字叫self
  • 类中的__init__方法会在类产生对象的时候自动执行

绑定方法

在类中定义的函数默认都是绑定给对象使用的,即对象来调 会自动将对象当做第一个参数传入

  1. class Student:
  2. school = '清华大学'
  3. # __init__方法不要自己去调用
  4. def __init__(self, name, age):
  5. self.name = name
  6. self.age = age
  7. def index_1(self, num):
  8. print('%s正在调用index_1方法' % self.name, num)
  9. def index_2(self):
  10. print('%s正在调用index_2方法' % self.name)
  11. def index_3(self, num):
  12. print('正在调用index_3方法', self, num)
  13. obj_1 = Student('kevin', 22)
  14. obj_2 = Student('tony', 18)
  15. Student.index_3(111, 2222) # 类调用类中函数 有几个参数就需要传几个参数
  16. # 正在调用index_2方法 111 2222
  17. obj_1.index_3(111) # 对象调用类中函数,会将当前调用的对象当做第一个参数自动传入
  18. # 正在调用index_3方法 <__main__.Student object at 0x7f8ff62ccf98> 111
  19. print(obj_1.index_1)
  20. # <bound method Student.index_1 of <__main__.Student object at 0x7fa3122cc978>>
  21. print(obj_1.index_2)
  22. # <bound method Student.index_2 of <__main__.Student object at 0x7fa3122cc978>>

动态方法与静态方法

动态方法

绑定对象的方法

  1. class Student:
  2. def run(self):
  3. print(self)
  4. Student.run("我是动态添加的") # 类调用绑定给对象的方法,有几个参数就需要传几个参数
  5. # 我是动态添加的
  6. obj = Student() # 对象调用绑定给对象的方法,会自动将对象当做第一个参数传入
  7. obj.run()
  8. # <__main__.Student object at 0x7fcf6ba57860>

绑定给类的方法

  1. class Student:
  2. @classmethod # 加上装饰器@classmethod后,该函数就绑定到了类
  3. def run(cls):
  4. print(cls)
  5. Student.run()
  6. # <class '__main__.Student'>
  7. obj = Student()
  8. obj.run()
  9. # <class '__main__.Student'>

补充:

绑定到类的方法就是专门给类用的,但其实对象也可以调用,只不过自动传入的第一个参数仍然是类,也就是说这种调用是没有意义的,并且容易引起混淆,这也是Python的对象系统与其他面向对象语言对象系统的区别之一

静态方法

  1. class Student:
  2. @staticmethod
  3. def run(a): # 调前都必须传固定的参数个数
  4. print(a)
  5. # 类调用静态方法要,自己传值
  6. Student.run('Hello')
  7. # Hello
  8. # 对象调用静态方法要,自己传值
  9. obj = Student()
  10. obj.run('kevin')
  11. # kevin

补充:

静态方法是类中的函数,不需要实例,静态方法主要用来存放逻辑逻辑性的代码,主要是一些逻辑属于类,但是和类本身没有交互,即在静态方法中,不会涉及到类中的方法和属性的操作,可以理解为将静态方法存在此类的名称空间中