Python 学习笔记 不定时更新

1 类和对象

学习的课程是https://www.bilibili.com/video/BV1ts411n7p1,老师讲的很细致

传入对象的时候,传的到底是什么

class Home:
    def __init__(self, area = 128):
        self.area = area
        self.items = []
        self.light = 'on'
        
    def __str__(self):
        
        msg = ''
        if len(self.items) > 0:
            msg =  '这个房子里有:' + ','.join([temp.getName() for temp in self.items])
            
        msg += '\n这个房子剩余面积为:' + str(self.area)
        return msg

    def addItems(self, item):
        self.area -= item.getArea()
        self.items.append(item)
        
    def testModifyObj(self):
        self.items[0].name = '席梦思'

        
class Item:
    def __init__(self, name, size):
        self.name = name
        self.area = size
        
    def getArea(self):
        return self.area
    
    def getName(self):
        return self.name
        
        
home = Home(200)
print(home)
bed1 = Item('大床', 4)
home.addItems(bed1)
print(home)
bed2 = Item('小床', 2)
home.addItems(bed2)
print(home)        
home.testModifyObj()
print(home)
print(bed1.name)

这里我定义了两个类。一个是Home,一个是Item类。

home对象接收了bed1,作为参数的传入。

为了搞明白这里接收的bed1到底是数据还是内存地址,在Home类中定义了一个testModifyObj()方法

经过验证,当我在接收了bed1以后,更改我接收的对象的name属性,实际的bed1也发生了修改。

因此,传入的是内存地址。

这也提醒了我们要定义方法去访问和修改对象的属性

2 类的继承

还是老王开枪。这里新定义一个枪叫狙击枪( Ju ), 继承 Gun()类。定义了新的子弹Juzidan,定义了杀伤力属性。

定义类的代码如下:

class Ren:
    def __init__(self, name):
        self.name = name
        self.xueliang = 100
        self.gun = None
        
    def anzidan(self, danjia, zidan):
        print('开始装子弹...')
        danjia.jinzidan(zidan)
        
    def andanjia(self, gun, danjia):
        print('开始安弹夹...')
        gun.shangdanjia(danjia)
        
    def naqiang(self, gun):
        print(self.name+'拿起了'+gun.name)
        self.gun = gun
        
    def kaiqiang(self, huairen):
        print(self.name + '对着'+huairen.name+'开了一枪')
        self.gun.jifa(huairen)
    
    def diaoxue(self, shashangli):
        if self.xueliang>0:
            self.xueliang -= shashangli
            if self.xueliang<0:
                self.xueliang = 0
                print(self.name + '已经挂了')
        else:
            print(self.name + '已经挂了,浪费子弹')
    
    def __str__(self):
        return self.name + '的血量为:' + str(self.xueliang) + '/100'
                

class Danjia:
    def __init__(self,name='弹夹', room=20):
        self.room = room
        self.name = name
        self.zidanlist = []
        
    def __str__(self):
        return  self.name + '的容量为:'+str(self.room) + '  子弹数量为:'+ str(len(self.zidanlist)) + '/' + str(self.room)
    
    def jinzidan(self, zidan):
        
        if self.room > len(self.zidanlist):
            self.zidanlist.append(zidan)
    
    def shangzidan(self):
        if len(self.zidanlist)>0:
            zidan = self.zidanlist[-1]
            self.zidanlist = self.zidanlist[:-1]
            print(zidan.name +'已经上膛···')
            return zidan
        else:
            print('子弹用尽')
        

class Zidan:
    def __init__(self):
        self.name = '子弹'
        self.shashangli = 5
    
    def kill(self, huairen):
        huairen.diaoxue(self.shashangli)


class Qiang:
    def __init__(self):
        self.danjia = None
        self.name = '步枪'
        
    def __str__(self):
        if self.danjia:
            return self.name + '当前有弹夹'+ ' 弹夹的子弹个数为' + str(len(self.danjia.zidanlist))
        else:
            return self.name + '当前无弹夹'
    
    def shangdanjia(self, danjia):
        if not self.danjia:
            self.danjia = danjia
    
    def jifa(self, huairen):
        zidan = self.danjia.shangzidan()
        zidan.kill(huairen)
    

class Ju(Qiang):
    def __init__(self):
        self.name = '狙击枪'
        self.danjia = None
    
    def jifa(self, huairen):
        if self.danjia.zidanlist[-1].name == '狙击子弹':
            juzidan = self.danjia.shangzidan()
            juzidan.kill(huairen)
        else:
            print('狙击枪需要配狙击子弹')


class Juzidan(Zidan):
    def __init__(self):
        self.name = '狙击子弹'
        self.shashangli = 100

程序的运行如下:

laowang = Ren("老王")
huairen = Ren('坏人')

danjia = Danjia('1号弹夹', 20)

ju = Ju()
print(ju)

juzidan = Juzidan()

laowang.anzidan(danjia,juzidan)

laowang.andanjia(ju, danjia)
print(ju)
laowang.naqiang(ju)
print(ju)
print(huairen)
laowang.kaiqiang(huairen)

print(huairen)

'''
狙击枪当前无弹夹
开始装子弹...
开始安弹夹...
狙击枪当前有弹夹 弹夹的子弹个数为1
老王拿起了狙击枪
狙击枪当前有弹夹 弹夹的子弹个数为1
坏人的血量为:100/100
老王对着坏人开了一枪
狙击子弹已经上膛···
坏人的血量为:0/100

'''

学到的知识点:

1、在设计类的方法之间相互传递的时候,比如人,要设置一个枪的属性;枪要设置弹夹的属性;弹夹要设置子弹的属性。好处是在调用方法的时候不需要再额外传入一个对象,直接用self.attri调用这个对象。逻辑上更加完整。

2、在继承类的过程中,如果需要重新用 def __init__(self)重新初始化类的属性,那么无法局部修改,必须全部修改。比如我定义了Juzidan这个类。本来只想定义一个self.name = '狙击子弹' , 但是定义完以后就没有了shashangli的属性。

 

3 函数定义的可变输入 def func(*args, **kwargs)

*args, **kwargs 这两个都是用来接收函数的输入参数。不同点在于,前一个接收的一个变量数据,变量的类型不限。而后一个接收的是一个" = "连接的键值对。

举例说明:

def A(a, *args, **kwargs):
    print(a)
    print(args)
    print(kwargs)
>>> A(1,2,3,4,c=10)
1
(2, 3, 4)
{'c': 10}

形参a 接收了 1  

*args 接收了 非键值对的 2,3,4,以元组的形式传递进来

**kwargs 接收了 c=10,并且以字典的形式传递进来

注意:

c=10 b不能写成 'c'=10, 否则会报错  keyword can't be an expression

除此以外,在接收参数的时候, *和** 还有解包的作用。

例如:

>>> A(1,*[1,2,3],c=10)
1
(1, 2, 3)
{'c': 10}

可以看到,如果加上一个*,就相当于把这个列表的变量全部取出来。等价于A(1,1,2,3 ,c=10)

注意:由于集合set 本身是去重的,因此不能使用 A(1,*{2,2,2},c=10),这个结果等价于A(1,2,c=10)

>>> A(1,*{'b':2})
1
('b',)
{}

如果将 * 用在字典前面,结果是 只解析了 字典的key,没有保存字典的value

这个时候,要用**来解包

>>> A(1,**{'b':2})
1
()
{'b': 2}

也就是说, A(1,**{'b':2}) 等价于 A(1, b=2)

但是还要注意:输入的字典的key如果与函数的形参名一致,则不能用**来解包,只能作为一个整体传入到元组里。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值