首页 > 编程语言 >Python进阶之面向对象编程

Python进阶之面向对象编程

时间:2024-05-10 09:14:04浏览次数:26  
标签:__ 进阶 Python self dict 面向对象编程 print age name

【一】人狗大战小游戏

【1】游戏前提分析

  • 人可以打狗,狗掉血,狗可以咬人,人掉血
  • 人的属性有名字、年龄、伤害、血量、类型
  • 狗的属性有名字、年龄、伤害、血量、类型

【2】游戏实现

(1)定义人和狗的属性

# 【1】用字典定义,代码较冗余
dog1 = {
    'name': '狗蛋',
    'd_type': '中华田园犬',
    'age': 2,
    'attack': 30,
    'blood': 150
}

dog2 = {
    'name': '小七',
    'd_type': '拉布拉多',
    'age': 3,
    'attack': 60,
    'blood': 250
}

person1 = {
    'name': '诺米',
    'p_type': '青年人',
    'age': 20,
    'attack': 100,
    'blood': 1000
}


# 【2】用函数封装
def get_dog(name, d_type, age, attack, blood):
    dog_data_dict = {
        'name': name,
        'd_type': d_type,
        'age': age,
        'attack': attack,
        'blood': blood
    }
    return dog_data_dict


def get_person(name, t_type, age, attack, blood):
    person_data_dict = {
        'name': name,
        't_type': t_type,
        'age': age,
        'attack': attack,
        'blood': blood
    }
    return person_data_dict

(2)人狗互咬功能实现

def get_dog(name, d_type, age, attack, blood):
    dog_data_dict = {
        'name': name,
        'd_type': d_type,
        'age': age,
        'attack': attack,
        'blood': blood
    }
    return dog_data_dict


def get_person(name, p_type, age, attack, blood):
    person_data_dict = {
        'name': name,
        'p_type': p_type,
        'age': age,
        'attack': attack,
        'blood': blood
    }
    return person_data_dict


def dog_attack_person(dog_dict, person_dict):
    person_dict['blood'] -= dog_dict['attack']
    print(
        f"{dog_dict['name']} 咬了 {person_dict['name']} 掉了{dog_dict['attack']}滴血,人还剩{person_dict['blood']}滴血")


def person_attack_dog(dog_dict, person_dict):
    dog_dict['blood'] -= person_dict['attack']
    print(
        f"{person_dict['name']} 咬了 {dog_dict['name']} 掉了{person_dict['attack']}滴血,狗还剩{dog_dict['blood']}滴血")


dog1 = get_dog(name='狗蛋', d_type='中华田园犬', age=2, attack=30, blood=150)
dog2 = get_dog(name='小七', d_type='拉布拉多', age=3, attack=60, blood=250)
person1 = get_person(name='诺米', p_type='青年人', age=20, attack=100, blood=1000)

dog_attack_person(dog_dict=dog1, person_dict=person1)
person_attack_dog(dog_dict=dog2, person_dict=person1)
# 狗蛋 咬了 诺米 掉了30滴血,人还剩970滴血
# 诺米 咬了 小七 掉了100滴血,狗还剩150滴血

(3)代码优化

# 狗的属性和狗的功能定义在一起
def get_dog(name, d_type, age, attack, blood):
    def dog_attack_person(dog_dict, person_dict):
        person_dict['blood'] -= dog_dict['attack']
        print(
            f"{dog_dict['name']} 咬了 {person_dict['name']} 掉了{dog_dict['attack']}滴血,人还剩{person_dict['blood']}滴血")

    dog_data_dict = {
        'name': name,
        'd_type': d_type,
        'age': age,
        'attack': attack,
        'blood': blood,
        'dog_attack_person': dog_attack_person
    }
    return dog_data_dict

#人的属性和人的功能定义在一起
def get_person(name, p_type, age, attack, blood):
    def person_attack_dog(dog_dict, person_dict):
        dog_dict['blood'] -= person_dict['attack']
        print(
            f"{person_dict['name']} 咬了 {dog_dict['name']} 掉了{person_dict['attack']}滴血,狗还剩{dog_dict['blood']}滴血")

    person_data_dict = {
        'name': name,
        'p_type': p_type,
        'age': age,
        'attack': attack,
        'blood': blood,
        'person_attack_dog': person_attack_dog
    }
    return person_data_dict


dog1 = get_dog(name='狗蛋', d_type='中华田园犬', age=2, attack=30, blood=150)
dog2 = get_dog(name='小七', d_type='拉布拉多', age=3, attack=60, blood=250)
person1 = get_person(name='诺米', p_type='青年人', age=20, attack=100, blood=1000)

person1['person_attack_dog'](dog_dict=dog1, person_dict=person1)
dog2['dog_attack_person'](dog_dict=dog2, person_dict=person1)
# 诺米 咬了 狗蛋 掉了100滴血,狗还剩50滴血
# 小七 咬了 诺米 掉了60滴血,人还剩940滴血

(4)小结

  • 上面的操作其实就是将数据与功能进行绑定,不再是所有的数据都可以调用任意的功能
  • 上述将数据与功能整合到一起的操作其实就是 面向对象编程的思想

【二】什么是面向过程和面向对象

【1】面向过程

  • 面向过程关键在于过程两个字,过程最终就是将程序流程化
  • 过程类似于流水线,分步骤来解决问题
  • 优点是将复杂的问题流程化,就是先干什么再干什么,逻辑比较清晰
  • 缺点是一套流水线或者流程就是用来解决一个问题,例如生产汽车

【2】面向对象

  • 面向对象关键在于对象两个字,过程最终就是将程序整合起来,对象用来盛放数据和功能

(1)面向对象的例子

  • 例如我们在学校,每一个角色都会对应其具有的责任和功能:
    • 比如一个学生具有姓名、年龄、性别、所在班级等,能做的活动有读书、写作、跑步、打篮球等
    • 比如一个老师也具有姓名、年龄、性别、所教学的班级等,能做的活动有教书、批改作业等
    • 比如一个运行员也具有姓名、年龄、性别、所在班级等,能做的活动有参加训练、比赛等
  • 当我们的角色和功能构建好以后,我们又需要创建几个学生、一些老师和运行员,让他们进行各项活动
    • 比如一个学生可以上课、写作业、运动
    • 比如一个老师可以教课、批改作业
    • 比如一个运动员可以训练、参加比赛

(2)面向对象的优缺点

  • 优点是将所有的功能和属性整合到一起,用什么拿什么,解决了程序的扩展性
  • 缺点是编程的复杂度远高于面向过程,不了解面向对象而立即上手基于它设计程序,极容易出现过度设计的问题

【3】类与对象

  • 类即类别、种类,是面向对象设计最重要的概念,对象是特征与技能的结合体,而类则是一系列对象相似的特征与技能的结合体

  • 类的好处就是我们可以把同一类对象相同的数据与功能存放到类里,而无需每个对象都重复存一份,这样每个对象里只需存自己独有的数据即可,极大地节省了空间

  • 所以说,对象其实就是用来存放数据与功能的容器,类则是用来存放多个对象相同的数据与功能的容器

(1)现实中

  • 在现实世界中:先有对象,再有类
  • 世界上肯定是先出现各种各样的实际存在的物体,然后随着人类文明的发展,人类站在不同的角度总结出了不同的种类,如人类、动物类、植物类等概念
  • 也就说,对象是具体的存在,而类仅仅只是一个概念,并不真实存在

(2)程序中

  • 在程序中:务必保证先定义类,后产生对象
  • 这与函数的使用是类似的,先定义函数,后调用函数,类也是一样的,在程序中需要先定义类,后调用类
  • 不一样的是,调用函数会执行函数体代码返回的是函数体执行的结果,而调用类会产生对象,返回的是对象

【三】面向对象编程

【1】类的定义

  • class关键字声明一个类
  • 在程序中定义出类,然后调用类产生对象
# 在程序中,我们要先声明一个类,在类中创建一个个对象
# 在程序中特征用变量标识,技能用函数标识
# 因而类中最常见的无非是:变量和函数的定义

# 方式一:
class Student(object)
# 方式二:
class Student()
# 方式三:
class Student
# 类名后面的 () 参数不写默认就是 object
class Student(object):
    school = "清华大学"

    def read(self):
        # self : 表示对象自己本身,
        print(f"我的学校是{self.school}")

# 通过类实例化得到一个对象
student = Student()
print(student)  # <__main__.Student object at 0x000001F2074B1340>
# 想用类里面的属性和方法
print(student.school_name)
print(student.read())  # None

【2】类的使用

(1)查看类的名称空间

  • 可以打印Student.__dict__来查看类的名称空间
class Student(object):
    school = '北京大学'

    def play(self):
        print(f"{self.school}的学生正在玩游戏!")


print(Student.__dict__)
# {'__module__': '__main__', 'school': '北京大学', 'play': <function Student.play at 0x000002BBDD83A7A0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}

(2)对象的实例化

  • 调用类的过程称为将类实例化,拿到的返回值就是程序中的对象,或称为一个实例
class Student(object):
    school = '北京大学'

    def play(self):
        print(f"{self.school}的学生正在玩游戏!")


# 每实例化一次Student类就得到一个新的对象
student1 = Student()
student2 = Student()
print(id(student1))  # 1690943387872
print(id(student2))  # 1690943135248

(3)修改对象的属性

[1] 通过类的名称空间修改属性

class Student(object):
    school = '北京大学'

    def play(self):
        print(f"{self.school}的学生正在玩游戏!")


obj1 = Student()
print(obj1.__dict__) # {}
obj1.__dict__['name'] = 'ligo'
obj1.__dict__['age'] = 18
obj1.__dict__['sex'] = '男'
print(obj1.__dict__) # {'name': 'ligo', 'age': 18, 'sex': '男'}
print(obj1.name)  # ligo

[2] 封装成函数

class Student(object):
    school = '北京大学'

    def play(self):
        print(f"{self.school}的学生正在玩游戏!")


def set_info(self, name, age, sex):
    self.name = name
    self.age = age
    self.sex = sex


obj1 = Student()
set_info(obj1, name='ligo', age=18, sex='男')
print(obj1.name)  # ligo

[3]封装成类的方法

class Student(object):
    school = '北京大学'

    def set_info(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def play(self):
        print(f"{self.school}的学生{self.name}正在玩游戏!")


obj1 = Student()
Student.set_info(obj1, name='ligo', age=18, sex='男')
print(obj1.name) # ligo
obj1.play()  # 北京大学的学生ligo正在玩游戏!

[4]类的魔法方法 __init__

class Student(object):
    school = '北京大学'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def choose(self, classroom):
        self.classroom = classroom

    def student_info(self):
        print(f'''
             -----学生信息如下----
                  姓名:{self.name}
                  年龄:{self.age}
                  性别:{self.sex}
                  班级:{self.classroom}
        ''')

    def play(self):
        print(f"{self.school}的学生{self.name}正在玩游戏!")


student = Student(name='ligo', age=18, sex='男')
print(student.__dict__)  # {'name': 'ligo', 'age': 18, 'sex': '男'}
print(student.name)  # ligo
student.classroom = '软件212'
print(student.classroom)  # 软件212
# 修改年龄
student.age = 20
student.student_info()
#              -----学生信息如下----
#                   姓名:ligo
#                   年龄:20
#                   性别:男
#                   班级:软件212

【3】属性访问

  • 类有两种属性:数据属性和函数属性,可以通过__dict__访问属性的值
  • 类属性
class Student(object):
    school = '北京大学'

    def __init__(self, name, age, sex, classroom):
        self.name = name
        self.age = age
        self.sex = sex
        self.classroom = classroom

    def student_info(self):
        print(f'''
             -----学生信息如下----
                  姓名:{self.name}
                  年龄:{self.age}
                  性别:{self.sex}
                  班级:{self.classroom}
        ''')

    def play(self):
        print(f"{self.school}的学生{self.name}正在玩游戏!")


print(Student.__dict__)
# {'__module__': '__main__', 'school': '北京大学', '__init__': <function Student.__init__ at 0x000002146A2AA7A0>, 'student_info': <function Student.student_info at 0x000002146A578B80>, 'play': <function Student.play at 0x000002146A5784C0>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
print(Student.school)  # 北京大学
print(Student.play)
# <function Student.play at 0x000002146A5784C0>
  • 对象属性
class Student(object):
    school = '北京大学'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def choose(self, classroom):
        self.classroom = classroom

    def student_info(self):
        print(f'''
             -----学生信息如下----
                  姓名:{self.name}
                  年龄:{self.age}
                  性别:{self.sex}
                  班级:{self.classroom}
        ''')

    def play(self):
        print(f"{self.school}的学生{self.name}正在玩游戏!")


student = Student(name='ligo', age=18, sex='男')
print(student.__dict__)  # {'name': 'ligo', 'age': 18, 'sex': '男'}
print(student.name)  # ligo
student.classroom = '软件212'
print(student.classroom)  # 软件212
# 修改年龄
student.age = 20
student.student_info()
#              -----学生信息如下----
#                   姓名:ligo
#                   年龄:20
#                   性别:男
#                   班级:软件212

【4】属性查找

  • 对象的名称空间里只存放着对象独有的属性,而对象们相似的属性是存放于类中的。
  • 对象在访问属性时,会优先从对象本身的__dict__中查找,未找到,则去类的__dict__中查找
# 查找顺序
# 首先在自己的对象中查找
# 自己找不到就去父类里面找
# 如果父类里面找不到,就去基类里面找
# 如果基类里面也没有,就去 object 里面找
# 如果还是找不到则报错
class Student(object):
    school = '北京大学'

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex

    def choose(self, classroom):
        self.classroom = classroom

    def student_info(self):
        print(f'''
             -----学生信息如下----
                  姓名:{self.name}
                  年龄:{self.age}
                  性别:{self.sex}
                  班级:{self.classroom}
        ''')

    def play(self):
        print(f"{self.school}的学生{self.name}正在玩游戏!")


student = Student(name='ligo', age=18, sex='男')
print(student.__dict__)  # {'name': 'ligo', 'age': 18, 'sex': '男'}
print(student.name)  # ligo
student.classroom = '软件212'
print(student.classroom)  # 软件212
# 修改年龄
student.age = 20
student.student_info()
#              -----学生信息如下----
#                   姓名:ligo
#                   年龄:20
#                   性别:男
#                   班级:软件212
student.play() 
# 北京大学的学生ligo正在玩游戏!

#类中定义的变量是类的数据属性,是共享给所有对象用的,指向相同的内存地址
print(id(student.school))  # 1948832565264
print(id(Student.school))  # 1948832565264

【5】list方法回顾

num_list1 = [1, 2, 3, 4, 5]
num_list2 = [6, 7, 8, 9, 10]
num_list1.append(3)
num_list2.append(1)
# 只会给指定的对象添加元素,不会给其他对象添加
print(num_list1)  # [1, 2, 3, 4, 5, 3]
print(num_list2)  # [6, 7, 8, 9, 10, 1]


class NumList(object):
    def __init__(self, num):
        self.num = num


num1 = NumList(num=1)
print(id(num1))  # 2629054930544
# 修改num的值不会改变num的id
num1.num = 2
print(id(num1))  # 2629054930544

【四】类的特殊属性

  • 类名.__name__ :类的名字(字符串)
  • 类名.__doc__:类的文档字符串
  • 类名.__base__:类的第一个父类
  • 类名.__bases__:类所有父类构成的元组
  • 类名.__dict__:类的字典属性
  • 类名.__module__:类定义所在的模块
  • 类名.__class__:实例对应的类(仅新式类中)
class Animal(object):
    ...


class People(Animal):
    '''这是一个人类的注释'''

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def run(self):
        print(f"{self.name} can run!")


print(People.__name__)
# People
print(People.__doc__)
# 这是一个人类的注释
print(People.__base__)
# <class '__main__.Animal'>
print(People.__bases__)
# (<class '__main__.Animal'>,)
print(People.__dict__)
# {'__module__': '__main__', '__doc__': '这是一个人类的注释', '__init__': <function People.__init__ at 0x00000131B53C35B0>, 'run': <function People.run at 0x00000131B5631990>}
print(People.__module__)
# __main__
print(People.__class__)
# <class 'type'>

标签:__,进阶,Python,self,dict,面向对象编程,print,age,name
From: https://www.cnblogs.com/ligo6/p/18183504

相关文章

  • python 基础习题 for循环
    1.用for循环打印出从1到10的所有整数,输出如下:12345678910  2.  声明如下变量:aString='Python'..........#请补齐以上省略号处的for循环语句,使得输出结果是:当前字母:P当前字母:y当前字母:t当前字母:h当前字母:o当前字母:n 最好用两种方法,一个使用不......
  • ROS话题通讯编写发布者(publisher)与订阅者(subscriber) Python
    学习参考:ROS/Tutorials/WritingPublisherSubscriber(python)-ROSWiki本文主要为了加强学习记忆,不是供人参考学习,如果想要学习点击链接系统学习; 在自己创建的工作空间下的src目录下创建一个新的功能包,在功能包中创建scripts文件夹,在内部放置.py源码; 下面剖析发布者源码......
  • 学习python步骤
    参考链接:https://zhuanlan.zhihu.com/p/693208513一、Python基础学习Python语言基础的路线可以分为以下几个阶段:Python3入门:了解Python3的安装方法、如何运行Python程序以及交互模式的使用,同时学习注释的添加方法。数据类型:掌握Python中的各种数据类型,包括数字、布尔值、......
  • PyCharm编辑器结合Black插件,轻松实现Python代码格式化
    1、简介使用Black对Python代码进行格式化,可使代码看起来更美观。但是,随着项目规模不断变大,对每个文件运行Black变得很繁琐。能否在文件保存后立即运行Black呢?本文就来介绍在PyCharm中实现这一目标的方法。2、安装Black首先,在虚拟环境中安装Black。$pipinstallblack ......
  • python教程6.6-发送邮件smtplib
    实现步骤: Python对SMTP⽀持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件,它对smtp协议进⾏了简单的封装。简单代码示例:发送html格式的邮件:在html中插入图片: ......
  • python学习----谁在说谎逻辑运算
    if__name__=='__main__':Li=[0,1]forainLi:forbinLi:forcinLi:zhang=(b==0)li=(c==0)wang=(a+b==0)if(zhang+li+wang==2anda+b+c=......
  • ubuntu22 python2 pyinstaller 打包报错:'NoneType' object has no attribute 'groups'
    前言最近有个需求,需要在ubnutu22上使用pyinstaller打包一个python2的文件。中间遇到了一些问题:pip2installpyinstaller报错解决方案:pip2installpyinstaller==3.6python2和python3的pyinstaller如何同时存在,我想把python2的pyinstaller命名为pyin......
  • python捕捉windows桌面
    使用mss模块截取屏幕图像#安装msspipinstallmssimportmss#获取屏幕尺寸withmss.mss()assct:monitor=sct.monitors[0]screen_width=monitor["width"]screen_height=monitor["height"]#设置捕获区域(这里设置为整个屏幕)monitor={"top":......
  • 如何使用python设计logo
    如何使用Python设计Logo一、引言在这篇文章中,将介绍如何使用Python来设计一个简单的Logo。将使用Python的第三方库PIL(PythonImagingLibrary)来实现这个功能。PIL是一个强大的图像处理库,可以帮助轻松地处理各种图像操作,如缩放、旋转、裁剪等。二、准备工作在开始设计Logo之前,......
  • 使用python中kivy库生成安卓APP
    kivy的安装官方推荐的方式是使用虚拟环境来进行安装和部署,关于虚拟环境的相关操作,在前面写过的一篇博客中有稍微详细一点的介绍,这里我们先给出操作步骤。假定我们已经在环境中用pip安装了virtualenv,那么我们先构建一个kivy的虚拟环境:[dechin@dechin-manjarokivy]$virtualenvk......