Python面向对象

面向对象编程的前戏

  # 人狗大战小游戏
  # 1.描述人和狗
  '''描述人和狗的方式1:使用字典一个个描述'''
   dog1 = {
       'name': '土狗',
       'type': '田园犬',
       'attack_val': 30,
       'life_val': 200
   }
   dog2 = {
       'name': '狮子',
       'type': '恶霸犬',
       'attack_val': 180,
       'life_val': 500
   }
   person1 = {
       'name': '老虎',
       'type': '猛男',
       'attack_val': 10,
       'life_val': 1000
   }

  # 描述人和狗 可以封装成函数,减少代码的冗余
  # 定义专门用来描述人和狗的一个函数  最少单独编写,写两个
  def get_person(name, gender, age, ty_type, attack_val, life_val):
      data_dict = {
          'name': name,  # 姓名
          'gender': gender,  # 性别
          'age': age,  # 年龄
          'ty_type': ty_type,  # 类型
          'attack_val': attack_val,  # 攻击力
          'life_val': life_val  # 血量
      }
      return data_dict
  def get_dog(name, ty_type, attack_val, life_val):
      data_dict = {
          'name': name,   # 姓名
          'ty_type': ty_type,  # 类型
          'attack_val': attack_val,  # 攻击力
          'life_val': life_val  # 血量
      }
      return data_dict
  # 给get_person传一些对应的值
  p1 = get_person('jason', 'male', 18, '猛男', 1000, 1000)
  p2 = get_person('wql', 'male', 20, '猛男', 10000, 10000)
  dog1 = get_dog('小黑', '藏獒', 100, 100)
  dog2 = get_dog('小白', '狮子', 1000, 1)


  def dog_attack(dog_obj, person_obj):
      """
      :param dog_obj: 接收一条狗
      :param person_obj: 接收一个人
      """
      # 使用最简单的掉血逻辑    血量减去对方的攻击力
      print('当前人的血量是:%s' % person_obj.get('life_val'))
      person_obj['life_val'] -= dog_obj.get('attack_val')  # 用人的血量减去狗的攻击力
      print('狗咬了人一口 人掉血%s 剩余血量:%s' % (dog_obj.get('attack_val'),person_obj['life_val']))

  def person_attack(person_obj, dog_obj):
      """
      :param person_obj: 接收一个人
      :param dog_obj: 接收一条狗
      """
      print('当前狗的血量是:%s' % dog_obj.get('life_val'))
      dog_obj['life_val'] -= person_obj.get('attack_val')  # 用狗的血量减去人的攻击力
      print('人锤了狗一下 狗掉血:%s 剩余血量:%s' % (person_obj.get('attack_val'), dog_obj['life_val']))

  # 狗咬人
  dog_attack(dog1, p1)
  # 人锤狗
  person_attack(p2,dog2)

  """如何做到只有人可以调用人的攻击动作 狗调用狗的攻击动作"""
  # 其实就是想让人的数据跟人的功能绑定 狗的数据跟狗的功能绑定
  def get_person(name, gender, age, t_type, attack_val, life_val):
      # 将人的攻击动作放在产生人的函数内
      def person_attack(person_obj, dog_obj):
          """
          :param person_obj: 接收一个人
          :param dog_obj: 接收一条狗
          """
          print('当前狗的血量是:%s' % dog_obj.get('life_val'))
          dog_obj['life_val'] -= person_obj.get('attack_val')
          print("""人:%s 锤了狗:%s 一下 狗掉血:%s 剩余血量:%s""" % (
          person_obj.get('name'), dog_obj.get('name'), person_obj.get('attack_val'), dog_obj['life_val']))

      data_dict = {
          'name': name,
          'gender': gender,
          'age': age,
          't_type': t_type,
          'attack_val': attack_val,
          'life_val': life_val,
          'person_attack':person_attack
      }
      return data_dict
  def get_dog(name, t_type, attack_val, life_val):
      def dog_attack(dog_obj, person_obj):
          """
          :param dog_obj: 接收一条狗
          :param person_obj: 接收一个人
          """
          # 使用最简答的掉血逻辑  血量减去对方攻击力
          print('当前人的血量是:%s' % person_obj.get('life_val'))
          person_obj['life_val'] -= dog_obj.get('attack_val')
          print("""狗:%s 咬了人:%s 一口 人掉血:%s 剩余血量:%s""" % (
          dog_obj.get('name'), person_obj.get('name'), dog_obj.get('attack_val'), person_obj['life_val']))
      data_dict = {
          'name': name,
          't_type': t_type,
          'attack_val': attack_val,
          'life_val': life_val,
          'dog_attack':dog_attack
      }
      return data_dict
  p1 = get_person('jason','male',18,'猛男',800, 1000)
  p2 = get_person('kevin','female',28,'淑女',10,100)
  dog1 = get_dog('小黑', '松狮犬', 300, 500)
  dog2 = get_dog('小白', '泰迪犬', 50, 200)
  p1['person_attack'](p1,dog1)
  dog1['dog_attack'](dog1,p2)
  """
  上述操作其实就是将数据与功能进行绑定 
      不再是所有的数据都可以调用任意的功能
  """
  # 上述将数据与功能整合到一起的操作其实就是 面向对象编程的思想

编程思想

  1.面向过程编程
	将程序的执行流程化 即分步操作 分步的过程中解决问题
  	eg:注册、登录、结算购物车...
      """注册:第一步获取用户名 第二步比对用户名数据 ..."""
      """结算:第一步获取购物车数据 第二步计算钱数   ..."""
	过程可以理解成是流水线 面向过程编程可以理解成是在创建一条流水线
  
  
  2.面向对象编程
  	核心就是'对象'二字 
  		对象其实就是一个"容器" 将数据与功能整合到一起
    只要是符合上述描述的事物都可以称之为是对象!!!
    	eg:
        人狗大战最后的函数内部含有数据和功能 可以称之为面向对象编程
        模块文件内部含有数据和功能 也可以称之为面向对象编程
    """仔细的想想会发现 python中一切皆对象!!!"""
    python针对面向对象编程提供了专门的语法 识别度更高 编写更精简
  		eg:人、动物、游戏角色
  """
  面向过程与面向对象两者没有优劣之分 具体要结合实际情况
  甚至很多时候两者是混合在一起的!!! 思想占据的比例不同而已
  """

类与对象的概念

  对象:数据与功能的结合体
  类:即类别、种类 相当于诸多对象公有的特征(数据、功能)!!!
  """
  在现实生活中 
  	人		 对象
  	一群人	         人类

  	狗	         对象
  	一群狗           犬类
  上述中的人类、犬类是用来描述什么的?
  	就是用来描述多个对象'相同'特征的名词
  		黄种人 黑种人 白种人都属于人类 但是彼此也有不同的特征
  			类只能描述出公共的特征!!! 不同的特征应该由对象自己描述!!!
  """
  ps:类其实也算对象>>>:一切皆对象

类与对象的创建

  # 人类
  class Student:
      # 人类的公共的数据
      school = '恶霸大学'
      print(school)   # 类型代码定义好了之后,立刻就会运行里面的数据
      # 人类的公共的功能
      def choice_course(self):  # 这里形参,不一定是要self,随便任何英文都可以
          print('学生选课功能')

  '''
      类体代码无需调用就会执行 产生类的名称空间
      语法结构
          class 类名:
              类体代码
          1.class是定义类的关键字
          2.类名类似于函数名 但是首字母推荐大写 用于区分
          3.类体代码就是存放对象公共数据和功能的地方
              数据:变量名 = 变量值
              功能:函数
  '''
  # 查看名称空间的方法>>>:__dict__
  print(Student.__dict__)  # 返回值是一个字典
  print(Student.__dict__['school'])  # 获取类中的属性
  print(Student.__dict__['choice_course'])  # 获取类中的属性
  '''类获取数据和功能有一个简便的方式>>>:就是句点符'''
  print(Student.school)
  print(Student.choice_course)

  '''任何产生对象:类名加括号'''
  obj1 = Student()  # 类名加括号就是在产生一个对象
  obj2 = Student()
  print(obj1.__dict__, obj2.__dict__)  # {} {}
  print(obj1.school)  # 恶霸大学
  print(obj2.choice_course())  # bound method  绑定方法
  '''产生一个对象之后,可以无障碍访问类中的数据'''
  print(obj1.school)  # 恶霸大学
  Student.school = '哈佛大学'     # Student.__dict__['school'] = '哈佛大学'  相当于修改了名字与值得一个对应关系
  print(obj1.school)  # 哈佛大学
  '''类里面的东西是公共的,修改之后,所有人来访问我值全部被改掉了'''

对象的实例化

  # 学生类
  class Student:
      def __init__(self, name, age, gender):
          '''该方法就一个功能>>>:给对象添加独有的数据'''
          self.name = name  # obj.__dict__['name'] = name
          self.age = age  # obj.__dict__['age'] = age
          self.gender = gender  # obj.__dict__['gender'] = gender

      # 学生类公共的数据
      school = '清华大学'

      # 学生类公共的功能
      def choose_course(self):
          print('学生选课功能')


   obj1 = Student()  # 目前对象没有自己独有的属性
   obj2 = Student()  # 目前对象没有自己独有的属性
   print(obj1.__dict__)  # 大白话就是给字典添加键值对
   print(obj2.__dict__)  # 大白话就是给字典添加键值对
  '''方案1:逐步给对象添加独有的数据'''
   obj1.__dict__['name'] = 'jason'  # obj1.name = 'jason'
   obj1.__dict__['age'] = 18  # obj1.age = 18
   obj1.__dict__['gender'] = 'male'  # obj1.gender = 'male'

   obj2.__dict__['name'] = 'kevin'  # obj2.name = 'kevin'
   obj2.__dict__['age'] = 2  # obj2.age = 28
   obj2.__dict__['gender'] = 'female'  # obj2.gender = 'female'
   print(obj1.__dict__,obj2.__dict__)
   print(obj1.name)  # jason
   print(obj2.name)  # kevin
  '''方案2:将冗余的添加步骤封装成函数'''
   def init(obj,name,age,gender):
       obj.name = name  # obj.__dict__['name'] = name
       obj.age = age  # obj.__dict__['age'] = age
       obj.gender = gender  # obj.__dict__['gender'] = gender
   init(obj1,'jason',18,'male')
   init(obj2,'kevin',28,'female')
   print(obj1.name)
   print(obj2.name)
  '''方案3:简单的封装成函数没有提现出面向对象整合的精髓>>>:将函数写到类中去'''
   obj1 = Student()
   obj2 = Student()
   Student.set_info(obj1,'jason',18,'male')
   Student.set_info(obj2,'kevin',28,'female')
   print(obj1.name)  # jason
   print(obj2.name)  # kevin
  '''方案4:类中针对给对象创建独有数据的函数名 专门定义了一个固定的方法'''
   obj1 = Student('jason', 18, 'male')
   obj2 = Student('kevin', 28, 'female')
   print(obj1.__dict__)
   print(obj2.__dict__)
  """
  类中的__init__方法会在类产生对象的时候自动执行
  类产生对象的具体步骤
      1.先创建一个没有独有数据的空对象  {}
      2.将空对象和类括号内传入的数据一并交给__init__执行
          __init__的第一个参数就是对象本身
              __init__(obj,name,age,gender)
      3.将创建好的对象自动返回
  给你提供这种方式能够减少代码的编写

  ps:针对括号内第一个形参self其实就是一个普通的变量名而已
  只不过该变量名将来专门接收对象的 所以给它起了个固定的名字叫self
"""

绑定方法

  """
  在类中定义的函数默认都是绑定给对象使用的
  	即对象来调 会自动将对象当做第一个参数传入
  """
  class Student:
      school = '清华大学'
      # __init__方法不要自己去调用 
      def __init__(self, name, age):
          self.name = name
          self.age = age

      def func(self):
          print('%s正在调用func方法'%self.name)

      def index(self):
          print('%s正在调用index方法'%self.name)

  obj1 = Student('jason', 18)
  # print(obj1)
  obj2 = Student('kevin', 28)
  # 类调用类中函数 有几个参数就需要传几个参数
  # Student.func(123,222)
  # 对象调用类中函数  会将当前调用的对象当做第一个参数自动传入
  # obj1.func()
  # obj2.func()
  # print(obj1.func)
  # print(obj2.index)
  '''所以应该能理解为什么类中所有的函数第一个参数都是self'''
posted @ 2022-04-07 00:45  吴起龙Lamb  阅读(49)  评论(0)    收藏  举报