Python学习笔记4---类和对象

一、类、对象的概念


类:                   一组具有相同或相似特征(属性)和行为(方法)的一系列(多个)对象的集合 【1:类名         2:类的属性[一组数据;在类的内部定义的变量]          3:类的方法[允许操作的方法(行为)] 】

对象:               类的实例化,类是对象的抽象化            (个人理解:“类”与C中的结构体相似,“对象”则是以结构体定义的变量)

1.1、创建一个类

#改进  __init__   可通过参数  传递实例属性
import time   #导入时间函数
class Labixiaoxin:
    name='小新'                               #在方法外部定义的变量称之为                   类属性
    age=5
    def __init__(self,dogname,job,love):         # __init__ 在创建对象是由编译器自动执行
        self.dogname=dogname                     #定义在方法内部且使用self定义的的数据称之为     实例属性
        self.job=job
        self.love=love
        pass
    def eat(self,food):                         #实例方法也可以使用参数传递
        print(food)
        pass
    @classmethod             #用 @classmethod  来修饰的就是              类方法
    def add(cls):
        print('春我部')
        pass
    @staticmethod        # @staticmethod 来修饰的就是               静态方法
    def gettime():
        print(time.strftime("%H:%M:%S",time.localtime()))          #打印当前时间
        pass
    pass
xiaoxin=Labixiaoxin('小白','幼稚园','娜娜子')
print(xiaoxin.love)
xiaoxin.eat('动感汉堡')
Labixiaoxin.gettime()
#输出:
#娜娜子
#动感汉堡
#09:33:25
  • 在“方法”外部定义的变量称之为-------类属性
  • 在"方法"内部定义且使用self关键字的变量称之为-------实例属性
  • "方法"可以传递参数,类似函数的使用
  • 类属性是可以被类对象和实例对象共同访问的
  • 实例属性只能被实例对象访问
  • 用 @classmethod  来修饰的就是--------------------------------类方法
  • 类方法中 可以修改类属性
  • @staticmethod 来修饰的且一般使用cls关键字来修饰称之为-----------------------------------静态方法
  • 一般情况下 不会使用实例对象去访问静态方法,静态方法中不会涉及到类方法类属性的操作

1.2、魔术方法

class Labixiaoxin:
    name='小新'                                   #在方法外部定义的变量称之为                   类属性
    age='5'
    def __init__(self,dogname,job,love):         # __init__ 在创建对象是由编译器自动执行
        self.dogname=dogname                     #定义在方法内部且使用self定义的的数据称之为     实例属性
        self.job=job
        self.love=love
        print('------执行__init__------------')
        pass
    def eat(self,food):                         #实例方法也可以使用参数传递
        print(food)
        pass
    def __new__(cls, *args, **kwargs):          #__new__    :创建并返回一个实例对象,调用一次就会得到一个对象   cls 是class的缩写
        print('------执行__new__---------------')
        return  object.__new__(cls)             #在这里创建真真的对象实例    必须有return
        pass

    def __str__(self):                          #__str__    :直接打印对象
        return '我是%s,年龄%s岁,宠物叫%s,现在上%s,喜欢%s'%(self.name,self.age,self.dogname,self.job,self.love)
    pass

pass
xiaoxin=Labixiaoxin('小白','幼稚园','娜娜子姐姐')
print(xiaoxin)

#------执行__new__---------------
#------执行__init__------------
#我是小新,年龄5岁,宠物叫小白,现在上幼稚园,喜欢娜娜子姐姐
  • “__init__”  在创建对象是由编译器自动执行
  • “__new__ ”  创建并返回一个实例对象,调用一次就会得到一个对象   cls 是class的缩写 , 必须有retrun才会创建一个对象
  • __str__    :直接打印对象
  • 创建一个对象时,先执行  “__new__ ”   再执行  “__init__”  

1.3、实例----双人决斗游戏

'''
属性:       角色名
            血量

方法:
            #JJJJ                   普通攻击            -5血量
            #unique skill           大招               -20血量
            #healing                治疗               +4血量
'''


#1、定义一个类
class Hero:
#2、初始化类的属性
    def __init__(self,name,hp):
        self.name=name
        self.hp=hp
        self.sking=0
        pass
#编写普通攻击的方法
    def JJJJ(self,enemy):
        enemy.hp-=5
        if self.sking<10:
            self.sking+=1    #普攻10次积攒大招
            pass
        print('[%s]攻击了[%s],使对方HP减少到[%d].'%(self.name,enemy.name,enemy.hp),end=' ')
        pass
#编写大招攻击方式
    def unique_skill(self,enemy):
        enemy.hp -= 20
        self.sking=0            #清空大招能量
        print('[%s]释放了大招,使[%s]HP减少到[%d].' %(self.name, enemy.name,enemy.hp),end=' ')
        pass
#编写治疗方式
    def healing(self):
        self.hp+=10
        print('[%s]使用了治疗术,恢复4HP,当前HP[%d].' % (self.name,self.hp),end=' ')
        pass

    def __str__(self):
        return '自身还剩[%d]HP,能量值积攒到[%d]'%(self.hp,self.sking)
        pass

#创建两个实例化对象
xmcx=Hero('西门吹雪',100)
dgqb=Hero('独孤求败',100)
import time             #加载时间函数
import random           #加载随机数
while True:
    if xmcx.hp==0 or dgqb.hp==0:
        break
    a=random.randint(1,2)   #生成1~2的随机数
    if a==1:
        xmcx.JJJJ(dgqb)
        print(xmcx)
        pass
    else:
        dgqb.JJJJ(xmcx)
        print(dgqb)
        pass
    if xmcx.sking>=10:
        xmcx.unique_skill(dgqb)     #西门吹雪 释放大招
        print(xmcx)
        pass
    elif dgqb.sking>=10:
        dgqb.unique_skill(xmcx)     #独孤求败 释放大招
        print(dgqb)
        pass
    time.sleep(1)   #延时1s
    pass
print('---------------------------决斗结束---------------------------')
if xmcx.hp!=0:
    print('----------------------[西门吹雪]获胜-----------------------')
    pass
else:
    print('-----------------------[独孤求败]获胜----------------------')



# [独孤求败]攻击了[西门吹雪],使对方HP减少到[95]. 自身还剩[100]HP,能量值积攒到[1]
# [独孤求败]攻击了[西门吹雪],使对方HP减少到[90]. 自身还剩[100]HP,能量值积攒到[2]
# [独孤求败]攻击了[西门吹雪],使对方HP减少到[85]. 自身还剩[100]HP,能量值积攒到[3]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[95]. 自身还剩[85]HP,能量值积攒到[1]
# [独孤求败]攻击了[西门吹雪],使对方HP减少到[80]. 自身还剩[95]HP,能量值积攒到[4]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[90]. 自身还剩[80]HP,能量值积攒到[2]
# [独孤求败]攻击了[西门吹雪],使对方HP减少到[75]. 自身还剩[90]HP,能量值积攒到[5]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[85]. 自身还剩[75]HP,能量值积攒到[3]
# [独孤求败]攻击了[西门吹雪],使对方HP减少到[70]. 自身还剩[85]HP,能量值积攒到[6]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[80]. 自身还剩[70]HP,能量值积攒到[4]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[75]. 自身还剩[70]HP,能量值积攒到[5]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[70]. 自身还剩[70]HP,能量值积攒到[6]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[65]. 自身还剩[70]HP,能量值积攒到[7]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[60]. 自身还剩[70]HP,能量值积攒到[8]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[55]. 自身还剩[70]HP,能量值积攒到[9]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[50]. 自身还剩[70]HP,能量值积攒到[10]
# [西门吹雪]释放了大招,使[独孤求败]HP减少到[30]. 自身还剩[70]HP,能量值积攒到[0]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[25]. 自身还剩[70]HP,能量值积攒到[1]
# [独孤求败]攻击了[西门吹雪],使对方HP减少到[65]. 自身还剩[25]HP,能量值积攒到[7]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[20]. 自身还剩[65]HP,能量值积攒到[2]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[15]. 自身还剩[65]HP,能量值积攒到[3]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[10]. 自身还剩[65]HP,能量值积攒到[4]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[5]. 自身还剩[65]HP,能量值积攒到[5]
# [西门吹雪]攻击了[独孤求败],使对方HP减少到[0]. 自身还剩[65]HP,能量值积攒到[6]
# ---------------------------决斗结束---------------------------
# ----------------------[西门吹雪]获胜-----------------------

1.4 析构方法


class Animal:
    def __init__(self,name):
        self.name=name
        print('对象被初始化')
        pass
    def __del__(self):
        print('当程序运行结束,解析器会自动的调用此函数 来释放内存')
        print('【%s】 这个对象被彻底删除了,内存也被释放了,这就是【析构方法】'%(self.name))
        pass
    pass

cat=Animal('蓝猫')
input('--------------等待输入---------')
dog=Animal('二哈')

#当手动删除某个对象时,也会调用析构方法
del dog  #收到删除dog对象      #当对象被删除后,则不能再被使用


# 对象被初始化
# --------------等待输入---------
# 对象被初始化
# 当程序运行结束,解析器会自动的调用此函数 来释放内存
# 【二哈】 这个对象被彻底删除了,内存也被释放了,这就是【析构方法】
# 当程序运行结束,解析器会自动的调用此函数 来释放内存
# 【蓝猫】 这个对象被彻底删除了,内存也被释放了,这就是【析构方法】
  • 析构方法 即 当使用完某个对象之后,将其删除用于释放内存
  • 或者是程序结束运行时将对象释放,从而释放内存

1.5 继承

#单继承:子类可以继承父类【属性和行为】(爸爸有的儿子都有,儿子有的爸爸不一定有)
class Animal:
    def eat(self):
        print('【%s】爱吃肉'%(self.name))
        pass

    def drink(self):
        print('【%s】爱喝牛奶'%(self.name))
        pass

    def __init__(self,name):
        self.name=name
        print('【%s】 __init__' % (self.name))
        pass
    def __del__(self):
        print('【%s】 __del__'%(self.name))
        pass
    pass


class dog(Animal):  #继承Animal父类
    def wwj(self):
        print('【%s】汪汪叫'%(self.name))
        pass
    pass

class cat(Animal):              #继承Animal父类
    def mmj(self):
        print('【%s】喵喵叫'%(self.name))
        pass
    pass

D=dog('小狗')
D.wwj()
D.eat()
C=cat('小猫')
C.mmj()
C.drink()

#多继承 继承Animal、dog、cat三个父类,因为dog,cat继承了Animal所以这里不用再写一次  这个叫做【简介继承】
class Pets(dog,cat):


    def DealShit(self):
        print('要铲屎官')
        pass
    def __init__(self,name):
        
        self.name=name
        pass
    pass

#peop对象继承了三个类,  A
people=Pets('铲屎官')
people.eat()
people.drink()
people.mmj()
people.wwj()
#当多个父类中存在相同的方法时 ,会根据定义【类】时的顺序查找       【自身>继承的第一个类>继承的第二个类】即广度优先原则
#这种原则下可实现 , 在子类中有与父类相同名字的方法,则子类会覆盖掉父类的方法, 即方法覆盖/重写





# 【小狗】 __init__
# 【小狗】汪汪叫
# 【小狗】爱吃肉
# 【小猫】 __init__
# 【小猫】喵喵叫
# 【小猫】爱喝牛奶
# 【铲屎官】爱吃肉
# 【铲屎官】爱喝牛奶
# 【铲屎官】喵喵叫
# 【铲屎官】汪汪叫
# 【小狗】 __del__
# 【小猫】 __del__
# 【铲屎官】 __del__
  •  继承:子类可以继承父类【属性和行为】(爸爸有的儿子都有,儿子有的爸爸不一定有)
  •  当一个新的对象继承的类继承了另外一个类,这样新的对象则继承了两个类-----------------------------------间接继承
  • 当多个父类中存在相同的方法时 ,会根据定义【类】时的顺序查找       【自身>继承的第一个类>继承的第二个类】---------------------------广度优先原则

  • 在子类中有与父类相同名字的方法,则子类会覆盖掉父类的方法, ----------------------------------------------方法覆盖/重写

  • ​​​​​

1.6 多态

#多态:多种形态,就是同一种行为,对于不同的【子类对象】有不同的行为表现
#多态的条件:
#1. 继承:发生在父类和子类之间
#2. 重写:子类重写父类的方法
class Animal:
    def Say_who(self):
        print('说我是一个动物')
        pass

    pass

class Dack(Animal):
    def Say_who(self):  #重写父类的方法
        print('我是可达鸭' )
        pass
    pass

class Bird(Animal):
    def Say_who(self):
        print('我是巴达兽')
        pass
    pass
class baolongshou(Animal):
    def Say_who(self):
        print('我是战斗暴龙兽')
        pass
    pass
def commonInvoke(obj):
    obj.Say_who()   #动态语言的动态类型   只要函数名(方法),且参数一样 不管前面的对象是谁,都可以通过这个方法输出
    pass


# dack=Dack('可达鸭')
# dack.Say_who()
listobj=[Dack(),Bird(),baolongshou()] #这种方式可以在不修改原代码的情况下任意的添加对象
for i in listobj:
    commonInvoke(i)    #多态可以增加程序的灵活性 和 扩展性
    pass


# 我是可达鸭
# 我是巴达兽
# 我是战斗暴龙兽

 

  • 多态:多种形态,就是同一种行为,对于不同的【子类对象】有不同的行为表现
  • 多态的条件:1. 继承:发生在父类和子类之间                 2. 重写:子类重写父类的方法
  • 动态语言的动态类型只要函数名(方法),和参数一样 不管前面的对象是谁,都可以通过这个方法输出
  •  多态可以增加程序的灵活性 和 扩展性

 

1.7 私有化属性/方法

私有化的应用场景:

  • 不让类的外部进行直接调用
  • 不让属性的值随意修改
  • 不让派生类【子类】继承
  • 属性前加两个下划线“__”,则此属性被私有化

1.71 私有化属性

#私有属性/方法的应用场景
#1.保护属性,不让类的外部进行直接调用
#2.保护属性,不让属性的值随意修改
#3.保护属性,不让派生类【子类】继承

class person:
    def __init__(self):
        self.__name='八神.太一'       #属性前加两个下划线“__”,则此属性被私有化
        self.age=10
        self.flag='勇气徽章'
        pass
    def __str__(self):
        return '【%s】的年龄是[%d]岁'%(self.__name,self.age)
    pass


yagushou=person()

#print(person.__name) #私有化的属性是不能再类的外部使用的  这样编译会出错
print(yagushou)


#【八神.太一】的年龄是[10]岁

1.72 私有化方法

#私有化方法
class Digimon:
    def __init__(self):
        self.__name='亚古兽'   #私有化属性
        pass
    def __Ultima(self):       #私有化方法
        print('【盖亚能量炮】')
        pass
    def Run(self):
        print('【%s】进化了,并释放了'%(self.__name),end=' ')
        self.__Ultima()    #调用私有化方法
        pass
    pass
a=Digimon()
a.Run()                 #上面都是通过【类】内部的【方法】访问了【私有属性/方法】

#也可以------通过【属性】的方式访问【私有属性】




#【亚古兽】进化了,并释放了 【盖亚能量炮】

 

1.8单例模式

 

单例模式 是一种常用的软件设计模式 , 目的是:确保某一个【类】值有一个实例存在,即一个【类】只能创建一个【对象】
#单例模式 是一种常用的软件设计模式 目的是:确保某一个【类】值有一个实例存在
#即一个【类】只能创建一个【对象】


#创建一个单例对象   基于__new__实现
class Digimon:
    def __init__(self):
        self.__name='亚古兽'   #私有化属性
        pass
    def __new__(cls, *args, **kwargs):
        #cls.Once=cls.__new__(cls)   #不能使用自身的new方法 容易造成深度递归,
        if not hasattr(cls,'Once'):#如果不存在则开始创建  hasattr函数用于判断对象是否包含对应的属性。
            cls.Once=super().__new__(cls,*args, **kwargs)   # 应该调用父类的new方法  ,super 表示 调用父类方法
        return cls.Once
    pass

a1=Digimon()
print(id(a1))

a2=Digimon()
print(id(a2))

#通过ID函数可以看出,假如是单例模式  只会创建一个对象
#1948826947344
#1948826947344

 

1.9 异常处理

 即代码执行出现异常,则会跳到指定的代码块,以下是应用举例。

#自定义异常
class ErrorToLong(Exception):
    def __init__(self,len):
       self.len=len
       pass

    def __str__(self):
        return '输入的长度为'+str(self.len)+'超长了'
    pass

try:
    name = input('请输入名字\n')
    if len(name) > 4:
        raise ErrorToLong(len(name))  # raise 后带一个异常类名称,表示引发执行类型的异常
    else:
        print('输入的名字是[%s]'%name)
        pass
    print('我是try') #捕获逻辑的代码
    pass
except NameError as msg:    #捕获命名错误
    print(msg)#捕获到错误,才会执行到这里
    pass
except IndexError as msg:   #捕获下标错误
    print(msg)
    pass
except Exception as msg:    #可捕获所有错误类型
    print(msg)
    pass
else:                       #没有出错会执行到这里
    print('当try里的代码执行,我才会执行')
    pass
finally:                    #不管有没有出错出错都会执行到这里
    print('我不管有没有出错 都会执行')
    pass

1.10     __slots__ 使用

只有在__slots__变量中的属性才能被添加,没有再其中的属性会添加失败。这种机制可以防止其他人调用类的时候胡乱添加属性和方法。__slots__属性子类不能继承,只有在当前类中有效。
使用 __slots__可节约内存空间
#__slots__     只有在__slots__变量中的属性才能被添加,没有再其中的属性会添加失败。
#这种机制可以防止其他人调用类的时候胡乱添加属性和方法
#__slots__属性子类不能继承,只有在当前类中有效

class Student(object):
    __slots__= ('name','age')                   #限制只有这两种属性
    def __str__(self):
        return '【%s】的年龄是【%d】'%(self.name,self.age)
    pass

xw=Student()
xw.name='小王'
xw.age=18
print(xw)
print(xw.__dict__) #假如不使用__slots__所有的属性都会存放在这里,
#定义了__slots__之后,类的实例就不能随意创建属性了,同时__dict__里不会再有数据了,从而节约内存空间

#xw.aaa=822    #不允许添加__slots__之外的属性

class substance(Student):
    __slots__=()
    pass
#如果子类中没有声明__slots__,那么不会继承父类的__slots__内容
#如果子类中 声明了__slots__,那么就会继承父类找那个__slots__的内容

 

 

 

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值