Python进阶:类和对象

Python核心编程:面向对象编程

面向对象

根据B站大学和廖雪峰的python整理而来
原文链接Serendipity

什么是面向对象

面向过程:思考的重点在于步骤。

面向对象:把问题分解成各个对象,描述对象在整个事情的行为。

引子

  • 人狗大战

    • 先创建很多狗,每个狗有各自的名字,品种,攻击力等

      • # 面向过程的思考
        dog1 = {
            "name": "小红",  # 创建dog1
            "d_type": "京巴",
            "attack_val": 40
        }
        
        def bite1(person):  # dog1咬人
            person.life_val -= 40
        
        
        dog2 = {"name": "小明",  # 创建dog2
                "d_type": "牧羊犬",
                "attack_val": 50
        }
        
        def bite2(person):  # dog2咬人
            person.life_val -= 50
        
        print(dog1)
        print(dog2)
         
        #以此类推创建dog3,doe4......
        #可以看到每当创建一个dog3就要重复很多代码,很是麻烦,有没有更好的办法的呢?
        #很负责任的跟大家说—— 没有
        #  是不可能的!
        #下面就是另一种编程思想
        
        
      • # 面向对象的思考
        #写一个函数,包含了每个狗的共同点
        attack_vals = {
            "京巴":40,
            "牧羊犬":50,
            "藏獒":60
            }
        
        def dog(name, d_type):
            data = {
                "name": name,
                "d_type": d_type,
                "life_val": 80
            }
        
            if d_type in attack_vals:  # 根据品种添加攻击力
                data["attack_val"] = attack_vals[d_type]
        
            return data
        
        
        dog1 = dog("小红", "京巴")  # 实体1
        dog2 = dog("小明", "牧羊犬")  # 实体2
        
        print(dog1)
        print(dog2)
            
        
    • 创建很多人

      • # 人也按照共同点创造
        def person(name, age):
            data = {
                "name": name,
                "age": age,
                "life_val": 100
            }
        
            if age > 18:
                data["attack_val"] = 50
            else:
                data["attack_val"] = 20
        
            return data
        
        
        P1 = person("阿福", 21)
        P2 = person("小璇", 17)
        P3 = person("小岚", 21)
        P4 = person("小乐", 21)
        
        print(P1)
        print(P2)
        print(P3)
        print(P4)
            
        
    • 人可以打狗,狗可以打人

      • #狗咬人
        def bite(dog_obj,person_obj):
            print(f"{dog_obj['name']}的攻击力:{dog_obj['attack_val']}")
            print(f"{person_obj['name']}的血量:{person_obj['life_val']} ")
            person_obj['life_val'] -= dog_obj['attack_val']
            print(f"{dog_obj['name']}咬了{person_obj['name']},人掉了{dog_obj['attack_val']}血量,还剩下{person_obj['life_val']}")
        
        bite(dog1,P1)
        
      • #打狗
        def fight_dog(person_obj,dog_obj):
            print(f"{person_obj['name']}的攻击力:{person_obj['attack_val']}")
            print(f"{dog_obj['name']}的血量:{dog_obj['life_val']} ")
            dog_obj['life_val'] -= person_obj['attack_val']
            print(f"{person_obj['name']}打了{dog_obj['name']},狗子没有了{person_obj['attack_val']}血量,还剩下{dog_obj['life_val']}")
            print()
            
        fight_dog(P1,dog1)
        
    • 思考

      • 上文的打狗函数是bite(dog_obj,person_obj),我们在实际传参的时候写成bite(person_obj,dog_obj)可以吗?
        从现实的角度来说,肯定是不可以的。因为bite()函数的狗咬人,理应传入狗的伤害值和人的生命值。
        但是从程序的角度来说,这样运行也没什么问题,因为计算机不知道你是人是狗。
        那么怎么让计算机知道你是人是狗呢?这就是这篇文章探讨的主要内容了!
        

类的语法

语法格式: class 类的名称():

class dog():  #创建一个狗类
    d_type = "藏獒"

    def say_hi(self):
        print(f"各位你们好,我的品种是{self.d_type}")

dog1 = dog() #类的一个实例化
print(dog1.d_type) #调用类的属性,属性一个静态的
dog1.say_hi() #该实列调用方法,方法是一个动作

类的初始化

class dog():  #创建一个狗类

    def __init__(self,name,d_type):  #初始化方法,构造方法,实例化时会自动执行,完成一些初始化操作
        self.name = name
        self.d_type = d_type
        self.life_val = 100
    def say_hi(self):
        print(f"各位你们好,我的品种是{self.d_type}")
        
dog1 = dog("小红","藏獒") #类的一个实例化
print(dog1.d_type) #调用类的属性,属性一个静态的
dog1.say_hi() #该实列调用方法,方法是一个动作

类属性的应用场景

类属性:类变量,也就是公共属性,所有实列共享

实例属性:实例变量,成员变量,每个实例独享

#类属性和实例调用类属性,若数值也是一样,内存空间是一样的
print(id(dog1.life_val))
print(id(dog2.life_val))

dog.life_val变量是一样,都是100,所以可以单独设置

class dog():  #创建一个狗类
	life_val = 100
    
    def __init__(self,name,d_type): 
        self.name = name
        self.d_type = d_type
       
    def say_hi(self):
        print(f"各位你们好,我的品种是{self.d_type}")

实列属性对自己不满意也可以改属性

#dog.life_val = 100
dog2.life_val = 200
print(id(dog2.life_val))

类之间的关系

  1. 依赖关系
  2. 关联关系
  3. 组合关系
  4. 聚合关系
  5. 继承关系,类的三大特性之一

访问限制

访问保护

在类的应用场景我们说到实例属性对自己不满意也可以改属性。

如果要让内部属性不被外部访问,可以在属性前面加上一些东西,如__

需要注意:变量名__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是private变量,所以,不能用__name____score__这样的变量名。

class dog():  #创建一个狗类
	
    
    def __init__(self,name,d_type): 
        self.__name = name
        self.__d_type = d_type
        self.life_val = 100
    #这样的话dog2.val = 200就不能成功。因为无法访问

如果说我们有时候真的需要修改life_val怎么办?可以给dog增加一个set_life_val方法:

class dog():  #创建一个狗类
    # life_val = 100
    def __init__(self,name,d_type):
        self.__name = name
        self.__d_type = d_type
        self.__life_val = 100

    def set_life_val(self,life):
        self.__life_val = life
        

除了修改,我们还需要访问life_val。但是现在显然是不能访问的,解决方案如下:

    def set_life_val(self):
        return self.__life_val

继承

当我们新定义一个class,可以从现有的class继承,新的这个class也就是子类。

比如我们定义一个二哈继承狗类。

class erha(dog):
    pass

这样的话,二哈拥有父类dog的全部功能。

获取对象信息

使用type()

使用type()可以判断类型

type(12345)
type(dog1)

使用isinstance()

对于class的继承关系。使用type()不方便。

>>> isinstance(erha1,erha)
True

因为erha是从dog继承下来的,所以erha1也是属于dog

>>> isinstance(erha1,dog)
True

使用dir()

获取一个对象的所有属性和方法,它返回一个包含字符串的list。

>>>dir(123)
['__abs__', '__add__',....... 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值