python31 -面向对象的推导-类-对象

今日学习

代码优化总结

编程思想

对象与类的概念

对象与类的创建

对象独有的数据

面向对象前戏

案例推导:人狗大战

1.'创造'人狗
-==================#推导直接手动模拟一个个人和狗==================================
person1 = {
    'name':'李白',
    'p_type':'刺客',
    'attack_val':800,
    'life_val':200
}
person2 = {
    'name':'盾山',
    'P_type':'坦克',
    'attack_val':'100',
    'life_val':1200
}

dog1 = {
    'name':'小黑狗',
    'd_type':'泰迪',
    'attack_val':'500',
    'life_val':800
}

dog2 = {
    'name':'小舔狗',
    'd_type': '比特',
    'attack_val':800,

}
---------总结-------------------------------------------------------
###如果定义人和狗的数量很多,这样写,太烦了。需要不停的写重复操作,所以封装成函数
#推导2,这个层是一整个例子。
==============------先定义人-----------==============================================

def get_person(name, gender, age, p_type, attack_val, life_val):
    """
    专用用于产生用户字典(创造人)
    :param name: 姓名
    :param gender: 性别
    :param age: 年龄
    :param d_type: 类型
    :param attack_val:攻击力
    :param life_val: 生命值
    :return: 人的字典(人)
    """
    person_obj = {
        'name': name,
        'gender': gender,
        'age': age,
        'p_type': p_type,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return person_obj

=========--------定义狗-------------===================================================


def get_dog(name, d_type, attack_val, life_val):
    """
    专门用于产生狗字典(狗)
    :param name: 狗的名字
    :param d_type: 狗的类型
    :param attack_val: 狗的攻击力
    :param life_val: 狗的生命值
    :return: 狗的字典(狗)
    """
    dog_obj = {
        'name': name,
        'd_type': d_type,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return dog_obj


# d1 = get_dog('小黄狗','中华田园犬',800, 5000)
# d2 = get_dog('小奶狗','哈士奇',100, 200)

"""推导步骤3: 让人和狗具备攻击的能力 本质其实就是定义两个函数供人和狗调用"""

=========================让人具备攻击能力===================================
def person_attack(person_obj, dog_obj):
    """
    专用提供给人调用 攻击狗
    :param person_obj: 传人数据(字典)
    :param dog_obj: 传狗数据(字典)
    """
    print('即将被攻击的狗:%s 当前血量:%s' % (dog_obj.get('name'), 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.get('life_val')))


def dog_attack(dog_obj, person_obj):
    """
    专用提供给狗调用 攻击人
    :param dog_obj: 传狗数据(字典)
    :param person_obj: 传人数据(字典)
    """
    print('即将被攻击的人:%s 当前血量:%s' % (person_obj.get('name'), 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.get('life_val')))


# 调用产生人和狗的函数
p1 = get_person('张飞', 'male', 18, '猛男', 8000, 90000)
p2 = get_person('李逵', 'female', 28, '淑女', 10, 200)
d1 = get_dog('小黄狗', '恶霸犬', 800, 8000)
d2 = get_dog('小黑狗', '巴哥犬', 200, 500)
# 调用攻击彼此的函数
# person_attack(p1, d1)
-------------执行结果1-----------------------------------------
# 即将被攻击的狗:小黄狗 当前血量:8000
# 人:张飞 锤了 狗:小黄狗 狗掉血:8000 剩余血量:0

dog_attack(p2, d2)
================执行结果2===========================================
即将被攻击的人:小黑狗 当前血量:500
狗:李逵 咬了 人:小黑狗 人掉血:10 剩余血量:490
 #是不是发现乱套了。 被攻击的人:小黑狗,函数被随意调用了。

面向对象

  • 本质:将特定的数据与特定的功能绑定到一起 将来只能彼此相互使用

从上面的例子
将人的数据跟人的功能绑定到一起
	只有人可以调用人的功能
将狗的数据跟狗的功能绑定到一起
	只有狗可以调用狗的功能
我们将数据与功能绑定到一起的操作起名为:'面向对象编程'

编程思想 面向对象|面向过程

面向过程是面向对象的基础,面向过程过程是解决唯一的不重复的工作,面向对象是尽可能的避免冗余的工作。

面向过程编程||
============

	截止昨天 我们所编写的代码都是面向过程编程
	过程其实就是流程 面向过程编程其实就是在执行一系列的流程
	eg:	注册功能   登录功能   冻结账户  ...
    就是按照指定的步骤依次执行 最终就可以得到想要的结果

---------------------------------------------------------------------------------------
面向对象编程||
============
核心就是'对象'二字
    	对象其实就是一个容器 里面将数据和功能绑定到了一起
	eg: 游戏人物 ...
    只负责创造出该人物以及该人物具备的功能 至于后续战绩如何无人知晓
"""
面向过程编程相当于让你给出一个问题的具体解决方案
面向对象编程相当于让你创造出一些事物之后不用你管
"""

上述两种编程思想没有优劣之分 仅仅是使用场景不同
甚至很多时候是两者混合使用
类别 定义
面向对象编程 面向对象是把整个需求按照特点、功能划分,将这些存在共性的部分封装成类(类实例化后才是对象),创建了对象不是为了完成某一个步骤,而是描述某个事物在解决问题的步骤中的行为
面向过程编程 可以说面向过程是一种基础的方法。. 它考虑的是实际地实现。. 一般的面向过程是从上往下步步求精,是一种以事件为中心的编程思想,编程的时候把解决问题的步骤分析出来,然后用函数把这些步骤实现,在一步一步的具体步骤中再按顺序调用函数。

对象与类的概念

  • 对象:数据与功能的结合体

  • :多个对象相同的数据和功能的结合体

=====================
类:0
"""
类比学习法
	一个人			对象
	多个人			人类
	
	一条狗			对象
	多条狗			犬类
"""
类主要用于记录多个对象相同的数据和功能
对象则用于记录多个对象不同的数据和功能
ps:在面向对象编程中 类仅仅是用于节省代码 对象才是核心

对象与类的问题:

1.如何定义类

2.如何定义对象

3.如何查看对象


对象与类的创建

  • 创建类的完整语法

  • 定义类名,不用加小括号

  • Pople类名,首字符大写。方便跟函数名做区分//

  • 定义即调用,就是说在定义时候就已经处于调用。

  • 类加括号就是产生一个对象|函数加括号就是调用
  • 类里面的定义的变量功能,所有的对象都可以去访问

# 类   例子
class People:                      #People定义类名      
    # 学生对象的公共数据 
    school = '清华大学'

    # 学生对象的公共方法
    def choice_course(self):
        print('正在选课')
#查看People的名称空间
print(People.__dict__)
-------------------------------------
1.class是定义类的关键字
2.People是类的名字
3.类体代码
	公共的数据\公共的方法
    
---------------再次敲重点-----------------------------------------
ps:类体代码在类定义阶段就会执行!!!People类为了跟函数命名区分,首字符会大写 跟函数有很大区别嗷。!!!!!!!!!
    
    
-----------------#1. 查看名称空间的方法 #比较麻烦-------------------------------------
 
print(People.__dict__)           # 使用该方法查看名称空间 可以看成是一个字典

------执行结果---------------

{'__module__': '__main__', 'school': '清华大学', 'choice_course': <function People.choice_course at 0x0000029788D98940>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}


-----------------------#2.取值- 比较麻烦-----------------------------------------

print(People.__dict__['school'])  # 使用字典的取值方式获取名字
--------执行结果------------
清华大学
-------------------------------------------------------------------------------------


print(People.__dict__.get('choice_course'))  # 使用字典的取值方式获取名字
<function People.choice_course at 0x000001CEC9F98940>

  • ---总结-------

  • '''在面向对象编程中 想要获取名称空间中的名字 可以采用句点符,python简化操作'''

  • print(People.school)    #相当于print(People.__dict__['school'])
    清华大学
    
class People:                      #People定义类名      
    # 学生对象的公共数据 
    school = '清华大学'

    # 学生对象的公共方法
    def choice_course(self):
        print('正在选课')
#查看People的名称空间
print(Student.school)
print(Student.choice_course)
-----------------------------------------------------------------------------------
'''类实例化产生对象>>>: 类名加括号'''    |函数体  加括号就是调用函数代码
-----------------------------------------------------------------------------------
stu1 = Student()                      
stu2 = Student()   
print(stu1.school)
print(stu2.school)
--------------------------------------------------------------------------------------
print(stu1) 			#类加括号就是产生一个对象
----执行结果-----------
<__main__.Student object at 0x000001D923B04A60>

print(stu2)  			#类加括号就是产生一个对象
-----执行结果-----------
# <__main__.Student object at 0x0000025E8A48F130>
--------------------------------------------------------------------------------------

# print(stu1.__dict__, stu2.__dict__)  # {} {}
# print(stu1.school)
# print(stu2.school)
# print(stu1.choice_course)
# print(stu2.choice_course)
------------------------------------------------------------------------------------
Student.school = '北京大学'  # 修改school键对应的值
print(stu1.school)
print(stu2.school)
-------------------------------------------------------------------------------------
"""
我们习惯将类或者对象句点符后面的东西称为属性名或者方法名 函数叫方法名。.school叫属性名
"""

对象独有的数据

1.什么叫对象独有的数据?

在对象自己的名称空间里有一些名字

# 学生类
class Student:
    # 学生对象的公共数据
    school = '清华大学'
    
    # 学生对象的公共方法
    def choice_course(self):
        print('正在选课')
--------------------------------------------------------------------------        
 '''推导思路1: 直接利用__dict__方法朝字典添加键值对'''
--------------------------------------------------------------------------
obj1 = Student()
print(obj1.__dict__) 
-----执行结果-----------
{}     #对象是空值


print(obj1.name)
---执行结果----------- #因为obj1对象 没有name的名字,会在类里找,类里也没有会报错
AttributeError: 'Student' object has no attribute 'name'
 
------对象如何拥有名字--【给obj1对象定义赋值】-------
obj1.__dict__['name'] = 'jason'    # 等价于 obj1.name = 'jason' 
obj1.__dict__['age'] = 18  		   # 等价于 obj1.age = 18
obj1.__dict__['gender'] = 'male'   # ...

--------打印【对象】里的内容----------------
print(obj1.__dict__)
----执行结果---------------
{'name': 'jason', 'age': 18, 'gender': 'male'}
print(obj1.name)
----执行结果---------------
jason
print(obj1.age)
----执行结果---------------
18
print(obj1.gender)
----执行结果---------------
male
print(obj1.school)
------执行结果--------------
清华大学

----------生成obj2对象,并产生内容-----------
obj2 = Student()
obj2.__dict__['name'] = 'kevin'
obj2.__dict__['age'] = 28
obj2.__dict__['gender'] = 'female'
print(obj2.name)
print(obj2.age)
print(obj2.gender)
print(obj2.school)

=====================================
!!如果给100个学生生成数据,岂不是很麻烦?
!!需要优化
!!定义函数,进行传参,将学生的基本信息设置成形参,传参赋值。参考推导思路2
=====================================

-----------------------------------------------------------------------------
'''推导思路2: 将添加独有数据的代码封装成函数'''
-----------------------------------------------------------------------------

def init(obj,name,age,gender):
    obj.__dict__['name'] = name
    obj.__dict__['age'] = age
    obj.__dict__['gender'] = gender
stu1 = Student()
stu2 = Student()
init(stu1,'jason',18,'male')          #通过init函数调用赋值传参。
init(stu2, 'kevin',28,'female')      

print(stu1.__dict__)  
-------执行结果-----------------
# {'name': 'jason', 'age': 18, 'gender': 'male'}

-------执行结果-----------------
print(stu2.__dict__)  
# {'name': 'kevin', 'age': 28, 'gender': 'female'}

============================
!!!! 1.这样只要每个学生进行定义传参,对象就会产生相对应的数据。
!!!!2.确实方便了很多。
!!!!3.但是在学生类里,本来产生的是学生对象数据,如果把狗,猫类的小动物调用,也会产生数据
!!!!4.所以接下来需要绑定 学生只能创建学生对象独有的数据,其他类别的不能调用
=========================

-------------------------------------------------------------------------------------
'''推导思路3: init函数是专用给学生对象创建独有的数据 其他对象不能调用>>>:面向对象思想   将数据和功能整合到一起
将函数封装到学生类中 这样只有学生类产生的对象才有资格访问
'''
-------------------------------------------------------------------------------------

class Student:
    """
    1.先产生一个空对象
    2.自动调用类里面的__init__方法 将产生的空对象当成第一个参数传入
    3.将产生的对象返回出去
    """
    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 choice_course(self):
        print('正在选课')
		self |   name |  age |gender
stu1 = Student('jason', 18, 'male')
print(stu1.__dict__)  # {'name': 'jason', 'age': 18, 'gender': 'male'}
stu2 = Student('kevin', 28, 'female')
print(stu2.__dict__)  # {'name': 'kevin', 'age': 28, 'gender': 'female'}
posted @ 2022-07-26 20:11  名字长的像一只老山羊  阅读(25)  评论(0编辑  收藏  举报