文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python--初始面向对象:类的相关知识,对象的相关知识

2023-01-30 21:59

关注

引子

假设你是一个开发人员,现在需要你开发一款叫做

当然很简单,两个角色,1个人物,1个boss,且人物和boss都有不同的技能,比如人物用觉醒技能秒了boss,掉了xx装备,boss用大招秒了人物,人物死亡,怎么描述这种不同的人物和他们的功能呢

根据之前掌握的知识点,写出了下面的代码来描述这两个角色

'''人物角色信息'''
def character(name, career, hp, ad):
    # name:人物昵称,career:人物职业, hp:人物血量, ad:人物攻击力
    data = {'name':name, 'career':career, 'hp':hp, 'ad':ad}
    return data

'''boss信息'''
def boss(name,level, hp, ad):
    # name:boss昵称, level:boss级别 hp:boss血量 ad:boss攻击力
    data = {'name':name, 'level':level, 'hp':hp, 'ad':ad}
    return data


上面两个方法相当于造了两个模子,游戏里的每个人物和每个boss都拥有相同的属性,游戏开始,你根据一个人或一个boss传入的具体信息来塑造一个具体的人或者boss,怎么生成呢?

# 传入1号boss具体信息
one_boss = boss('魔龙教主', '主宰boss', 10000, 5000)

# 传入1号人物具体信息
one_character = character('一刀秒杀', '战士', 99999, 99999)


两个角色对象生成了,boss和人物还有不同的功能呀,boss放技能打人物,人物放技能打boss,对不对?怎么实现呢?想到了,可以每个功能函数在写一个,想执行哪个功能,直接调用就可以了,对不?

def awakening(boss):
    print('玩家:{}对{}释放觉醒技'.format(one_character['name'], one_boss['name']))
    if one_character['ad'] - one_boss['hp'] >= 0:
        print('玩家:{}杀死了{},爆出一把主宰之剑'.format(one_character['name'], one_boss['name']))

def dragon_breath(character):
    print('boss:{}对{}释放了龙息'.format(one_boss['name'], one_character['name']))


整个代码

'''人物角色信息'''
def character(name, career, hp, ad):
    # name:人物昵称,career:人物职业, hp:人物血量, ad:人物攻击力
    data = {'name':name, 'career':career, 'hp':hp, 'ad':ad}
    return data

'''boss信息'''
def boss(name,level, hp, ad):
    # name:boss昵称, level:boss级别 hp:boss血量 ad:boss攻击力
    data = {'name':name, 'level':level, 'hp':hp, 'ad':ad}
    return data

# 传入1号boss具体信息
one_boss = boss('魔龙教主', '主宰boss', 10000, 5000)

# 传入1号人物具体信息
one_character = character('一刀秒杀', '战士', 99999, 99999)

def awakening(boss):
    print('玩家:{}对{}释放觉醒技'.format(one_character['name'], one_boss['name']))
    if one_character['ad'] - one_boss['hp'] >= 0:
        print('玩家:{}杀死了{},爆出一把主宰之剑'.format(one_character['name'], one_boss['name']))

def dragon_breath(character):
    print('boss:{}对{}释放了龙息'.format(one_boss['name'], one_character['name']))
awakening(one_character)
dragon_breath(one_boss)

执行结果如下

玩家:一刀秒杀对魔龙教主释放觉醒技

玩家:一刀秒杀杀死了魔龙教主,爆出一把主宰之剑

boss:魔龙教主对一刀秒杀释放了龙息


但是这样会有一个问题,人物和boss的信息可以互传,很容易搞混了,怎么办?接着该

'''人物角色信息'''
def character(name, career, hp, ad):
    # name:人物昵称,career:人物职业, hp:人物血量, ad:人物攻击力
    data = {'name':name, 'career':career, 'hp':hp, 'ad':ad}
    def awakening(boss):
        print('玩家:{}对{}释放觉醒技'.format(one_character['name'], one_boss['name']))
        if one_character['ad'] - one_boss['hp'] >= 0:
            print('玩家:{}杀死了{},爆出一把主宰之剑'.format(one_character['name'], one_boss['name']))
    data['awakening'] = awakening
    return data

'''boss信息'''
def boss(name,level, hp, ad):
    # name:boss昵称, level:boss级别 hp:boss血量 ad:boss攻击力
    data = {'name':name, 'level':level, 'hp':hp, 'ad':ad}
    def dragon_breath(character):
        print('boss:{}对{}释放了龙息'.format(one_boss['name'], one_character['name']))
    data['dragon_breath'] = dragon_breath
    return data

# 传入1号boss具体信息
one_boss = boss('魔龙教主', '主宰boss', 10000, 5000)

# 传入1号人物具体信息
one_character = character('一刀秒杀', '战士', 99999, 99999)

# 1号人物使用觉醒技攻击(1号boss)
one_character['awakening'](one_boss)

执行结果

玩家:一刀秒杀对魔龙教主释放觉醒技

玩家:一刀秒杀杀死了魔龙教主,爆出一把主宰之剑


把人物信息和人物技能放到一个函数里面,boss信息和boss技能放到一个函数里面,防止混用,其实就是简单的面向对象编程,归类!


面向过程VS面向对象

面向过程的程序设计的核心是过程(流水线式思维),过程即解决问题的步骤,面对过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西

有点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可

缺点是:一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身

应用场景:一旦完成基本很少改变的场景,著名的列子有Linux内核,git,以及apache http server等


面向对象的程序设计的核心是对象(上帝式思维),要理解对象为何物,必须把自己当成上帝,上帝眼里世间存在的万物皆为对象,不存在的也可以创造出来。

面向对象的程序设计

优点是:解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏一个人物参数的特征和技能修改都很容易。

缺点:可控性差,无法向面向过程的程序设计流水式的可以很精准的预测问题的处理流程和结果,面向对象的程序一旦开始就由对象之间的交互解决问题,即便是上帝也无法预测最终结果。于是我们经常看到一个游戏人物的参数的修改极有可能影响一个游戏的平衡

应用场景:需求经常变化的软件,一般需求的变化都集中在用户层,互联网应用,企业内部软件,游戏等都是面向对象的程序设计大显身手的好地方


在python中面向对象的程序设计并不是全部

面向对象变成可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率,另外,基于面向对象的程序可以使他人更加容易理解你的代码逻辑,从而使团队开发变得更从容

了解一些名词:类,对象,实例,实例化

类:具有相同特征的一类事物

对象/实例:具体的某一个事物(隔壁班班花,楼下少妇)

实例化:类---->对象的过程(这在生活中表现的不明显,后面会在慢慢解释)


初始类和对象

python中一切皆为对象,类型的本质就是类。

在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是‘类’,对象则是这一类事物中具体的一个。

使用面向对象,首写字母是大写(标准写法,规范写法)

class Person:
    静态变量 = 123
print(Person.__dict__)  #内置的双下方法,查看静态变量

执行结果

{'__doc__': None, '__module__': '__main__', '__dict__':


访问静态变量

class Person:
    静态变量 = 123
print(Person.__dict__['静态变量'])  # 访问静态变量

执行结果

123


查看静态变量的第一种方式

class Person:
    静态变量 = 123
print(Person.__dict__)  # 内置的双下方法
print(Person.__dict__['静态变量'])  # 内置方法__dict__只能访问静态变量
Person.__dict__['静态变量'] = 456   # 使用内置__dict__['']方法修改静态变量
print(Person.__dict__['静态变量'])  # 执行报错,内置方法__dict__只能访问静态变量,不能修改

执行结果

{'__weakref__':

Traceback (most recent call last):

  File "D:/python11_quanzhan/day16/lianxi.py", line 108, in

123

    Person.__dict__['静态变量'] = 456

TypeError: 'mappingproxy' object does not support item assignment


查看静态变量的第二种方式

class Person:
    静态变量 = 123
print(Person.静态变量)  # 打印静态变量 
Person.静态变量 = 456  # 修改静态变量
print(Person.静态变量)  # 打印修改后的静态变量

执行结果

123

456


删除静态变量的方法

class Person:
    静态变量 = 123
del Person.静态变量
print(Person.__dict__)

执行结果

{'__dict__':

可以看到  静态变量:123已经删除


类名

    引用静态变量

        1.类名.__dict__['静态变量名'] 可以查看,但是不能删改

        2.类名.静态变量名 直接就可以访问,可以删改

        3.del 类名.静态变量名 删除一个静态变量


动态变量就是函数

class Person:
    静态变量 = 123
    role = 'person'
    def func(self):  # 默认带一个参数self,方法,动态属性
        print(1234567)
print(Person.静态变量)  # 打印静态变量
Person.func()  # 执行动态属性,也就是执行类里面的func()函数

执行结果,报错,缺少一个参数

Traceback (most recent call last):

123

  File "D:/python11_quanzhan/day16/lianxi.py", line 128, in

    Person.func()  # 执行动态属性,也就是执行类里面的func()函数

TypeError: func() missing 1 required positional argument: 'self'


传入一个参数,在执行,代码如下

class Person:
    静态变量 = 123
    role = 'person'
    def func(self):  # 默认带一个参数self,方法,动态属性
        print(1234567)
print(Person.静态变量)  # 打印静态变量
Person.func(1)  # 执行动态属性,也就是执行类里面的func()函数,传入一个参数1(实参)

执行结果

123

1234567

Why?为什么传一个参数,就可以执行了?

引用动态变量

1 类名.方法名 查看这个方法的内存地址

2 类名.方法名(实参) 调用了这个方法,必须传一个实参,这个实参传给了self

只要是类的方法,必须要传self。self的名字(虽然可以改,但是不建议),是一种标准写法,约定俗成


调用类名加括号,创造一个对象

创造一个命名空间,唯一属于对象

st = Person()  # 创造一个对象

st是对象

Person是类

对象=类名()

类变成对象的过程,是实例化的过程

blob.png

实例化,是产生实例的过程

创造一个对象-实例化

产生一个实例(对象)的过程

对象=类名()

st = Person()

实例化的过程

1 创造一个实例,将会作为一个实际参数

2 自动触发一个__init__的方法,并且把实例以参数的形式传递给__init__方法中的self形参

3 执行完__init__方法之后,会将self自动返回给st

class Person:
    role = 'person'  # 静态属性

    def __init__(self):  # 动态属性 方法(函数) 默认带一个参数self
        print('执行了!')
        print(self)
        
st = Person()
print(st)

执行结果

执行了!

内存地址是一样的

init里面,不能加return


例2

class Person:
    role = 'person'  # 静态属性

    def __init__(self, name):
        print('执行我了!')
        print(self, name)
st = Person('st_sb')
print(st)

执行结果,name和self是没有关系的

执行我了!


self默认是一个空字典

class Person:
    role = 'person'  # 静态属性

    def __init__(self):
        print(self.__dict__)  # 打印self
st = Person()

执行结果

{}


类和外部唯一的联系,就是self

blob.png

这样,st就拥有自己的字典

class Person:
    def __init__(self,name,sex,hp,ad):
        self.name = name
        self.sex = sex
        self.hp = hp
        self.ad = ad


st = Person('st_sb','人妖',1,5)
print(st.__dict__)

执行结果

{'name': 'st_sb', 'hp': 1, 'ad': 5, 'sex': '人妖'}


例2

class Person:
    def __init__(self,name,sex,hp,ad):
        self.name = name
        self.sex = sex
        self.hp = hp
        self.ad = ad


st = Person('st_sb','人妖',1,5)
boss = Person('深渊领主','不详',9999,9999)
print(st.__dict__)
print(boss.__dict__)

执行结果

{'name': 'st_sb', 'ad': 5, 'sex': '人妖', 'hp': 1}

{'name': '深渊领主', 'ad': 9999, 'sex': '不详', 'hp': 9999}

每次调用Person()都会产生一个新的内存空间

空间会返回给调用者

blob.png

类里面的方法,没有顺序之分,一般吧init放到第一个,在类里面的def一般叫方法

class Person:
    def __init__(self,name,sex,hp,ad):
        self.name = name
        self.sex = sex
        self.hp = hp
        self.ad = ad

    def attack(self):
        print('{}发起了一次攻击'.format(self.name))
st = Person('st_sb', '不详',99,99)
Person.attack(st)  # 有一个简写
st.attack()
boss = Person('深渊领主','不详',9999,9999)
Person.attack(boss)  # 简写
boss.attack()

执行结果

st_sb发起了一次攻击

st_sb发起了一次攻击

深渊领主发起了一次攻击

深渊领主发起了一次攻击

方法的调用:(推荐使用第二种)

类名.方法名(对象名)  # 那么方法中的self参数就指向这个对象

对象名.方法名()      # 这样写,相当于 方法中的self参数直接指向这个对象

attack是和Person关联起来的,所以外部可以直接调用attack方法


小结

class 类名:

    def __init__(self,参数1,参数2):

        self.对象的属性1 = 参数1

        self.对象的属性2 = 参数2


    def 方法名(self):pass


    def 方法名2(self):pass


对象名 = 类名(1,2)  #对象就是实例,代表一个具体的东西

                  #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法

                  #括号里传参数,参数不需要传self,其他与init中的形参一一对应

                  #结果返回一个对象

对象名.对象的属性1   #查看对象的属性,直接用 对象名.属性名 即可

对象名.方法名()     #调用类中的方法,直接用 对象名.方法名() 即可


练习题:(使用类的方式)

练习一:在终端输出如下信息

小明,10岁,男,上山去砍柴

小明,10岁,男,开车去东北

小明,10岁,男,最爱大保健

老李,90岁,男,上山去砍柴

老李,90岁,男,开车去东北

老李,90岁,男,最爱大保健

老张......

class Info(object):
    def __init__(self, name, age, sex='男', content=('上山去砍柴', '开车去东北', '最爱大保健')):
        self.name = name
        self.age = age
        self.sex = sex
        self.content = content

    def run(self):
        for i in self.content:
            print('{},{},{},{}'.format(self.name, self.age, self.sex, i))


st = Info('小明', '10岁')
xt = Info('老李', '90岁')
st.run()
xt.run()

执行结果

小明,10岁,男,上山去砍柴

小明,10岁,男,开车去东北

小明,10岁,男,最爱大保健

老李,90岁,男,上山去砍柴

老李,90岁,男,开车去东北

老李,90岁,男,最爱大保健


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯