python 类和对象(属性、初始化函数__init__、方法、继承(重写、多层继承、多重继承)、动态属性 【反射】setattr)

类与对象

类和对象:抽象 + 概念很多。 == 概念类比生活中例子理解就可以。

  • 对象 实例
  • 属性: 类属性 和实例属性
  • 方法: 实例方法 和类方法
  • init函数
  • self
  • 继承
  • 动态属性 反射

类: 人类 猫类 狗类 植物类,类是一类事物统称,这类事物具备共同特征。
对象:Mimanchi,折耳猫,汪汪,绿萝,类里面的一个实实在在的个体成员。 是类的具象化存在。
属性: 类或者对象的特征和状态。 【人:眼睛,肤色: 黄色 身高,白色,卷毛狗】

  • 类属性:类共同特征 == 眼睛 人类的属性
  • 对象属性:某个个人才有的特征 不是类的所有群体都有特征。 == 耳洞 个人的属性
    方法:类和对象的动作和行为。【吃饭 走路 打篮球 唱歌】 == 类里面函数

类: 人类 猫类 狗类 植物类,类是一类事物统称,这类事物具备共同特征。
对象:Mimanchi,折耳猫,汪汪,绿萝,类里面的一个实实在在的个体成员。 是类的具象化存在。
属性: 类或者对象的特征和状态。 【人:眼睛,肤色: 黄色 身高,白色,卷毛狗】

  • 类属性:类共同特征 == 眼睛 人类的属性
  • 对象属性:某个个人才有的特征 不是类的所有群体都有特征。 == 耳洞 个人的属性
    方法:类和对象的动作和行为。【吃饭 走路 打篮球 唱歌】 == 类里面函数

举例: 我今天开着黑色的特斯拉去上班,路上没有电了,我充了电。
–针对以上的话,分析一下 哪些是类 对象 属性 方法。
涉及到的人和物 : 我 车 电
类: 人类,车类,电类,路类
对象:我,特斯拉,充的电,上班路
属性:【特征和状态】黑色的,没有电了
方法:开车,上班,被开着走,充电… 【类和对象的动作和行为】

定义类:class
class 类名:
类里面具体内容
类名: 符合标识符命名规则,参考变量的命名方式【蛇形命名】,类一般都是用大驼峰命名。

  • pass: 占位 避免语法错误。 没有任何实质意义。
    实例化对象:类的名字加一个括号 就可以得到一个对象。
class Car:
    pass

# 调用类
print(Car)
# 从类里得到对象 【实例化】
my_car = Car()  # 对象1 -类的名字加一个括号
print(my_car)
your_car = Car()  # 对象2
print(your_car)

属性

属性:类或者对象的特征和状态。属性名字 = 属性值

  • 类属性:类共同特征 ==直接写在类下面的属性定义
  • 对象【实例】属性:某个个人才有的特征 不是类的所有群体都有特征。
    注意: 实例属性比类属性用的更多,如果搞不清楚是应该用实例属性还是类属性 统一用实例属性。

1、通过类获取类属性的值 类.属性名字
2、通过对象获取类的属性 对象.属性名字
3、修改类属性值 == 在类外面修改类属性的值。
4、可以增加类的属性 Car.属性名 = 属性值

class Car:
    # 类属性 定义车类的属性
    wheel = True
    engine = True


# 获取类属性的值  类.属性名字
# print(Car.wheel)

#  类的属性写在类里面的 类似于函数的局部变量 不能在类外面调用
# print(engine)  # 不行,报错。

# 修改类属性值 == 在类外面修改类属性的值。
# Car.wheel = "lemon"
# print(Car.wheel)
#
# # 增加类的属性
# Car.body = True
# print(Car.body)

# 类的属性可以通过对象调用  对象.属性名字
my_car = Car()
print("之前的车轮:",my_car.wheel)

# 通过对象 修改了 属性值。 == 实例属性
my_car.wheel = "Amazing"
print("改装后的车轮:",my_car.wheel)
print("类的属性",Car.wheel)

初始化函数: __init__函数

初始化函数: __init__函数 == 名字是固定的 不能修改

  • 目的: 在类里面初始化实例属性。在实例化对象的时候可以直接调用这个初始化函数,初始化一些具体的属性值。
  • 这个初始化的属性值是可以每个对象可以不一样的。

1、实例化一个对象的过程中 就会自动调用init函数 执行init函数里的代码。
2、init函数不能写返回值。不能写return。
3、init函数 不是类里面一定定义的 看我们定义类的需求。

问题:
1、self是啥?
2、怎么在init函数里定义实例属性?

1、什么是self?

  • 在类里面def 函数的时候,默认会在括号里加上一个self。
  • self指的对象本身 ==车在车厂 成为my_car的车
  • 一个对象在类里面 就是self。

2、怎么在init函数里定义实例属性?–对象属性 self对象

实例属性:
1、可以通过实例调用: 在类里面可以通过self调用
2、不可以通过类调用。

# 定义类
class Car:
    # 类属性 定义车类的属性
    wheel = True
    engine = True

    def __init__(self):
        """
         # 在类里面订一个初始化函数 - init函数
        """
        # 定义实例属性 -对象属性,前面一定要self
        self.color = "黑色"  # self.属性名 = 属性值  ==实例属性
        self.logo = "Tesla"   #  ==实例属性
        self.wheel = False
        print(f"类里面的对象{self}")
        print("正在生产一辆车....")

# 实例化对象
my_car = Car()  # my_car 相当于self
print("实例化之后成为我的车:",my_car)

# 调用实例属性  # 通过实例调用实例属性
print(my_car.color)
print(my_car.logo)

# 在类外面修改实例属性
my_car.color = "红色"
print(my_car.color)

# 实例化另外一个对象 也可以调用实例属性
your_car = Car()
print(your_car.color)
print(your_car.logo)

# 如果类属性和实例属性都有同样属性名 实例调用 得到实例属性值。
print("这个是确认实例和类型都有的时候:",your_car.wheel)

# 类可以调用实例属性么?==不可以,实例属性不可以通过类调用
# print(Car.color)

__init__函数的参数化

初始化函数: __init__函数 == 名字是固定的 不能修改

  • 目的: 在类里面初始化实例属性。在实例化对象的时候可以直接调用这个初始化函数,初始化一些具体的属性值。
  • 这个初始化的属性值是可以每个对象可以不一样的。

1、实例化一个对象的过程中 就会自动调用init函数 执行init函数里的代码。
2、init函数不能写返回值。不能写return。
3、init函数 不是类里面一定定义的 看我们定义类的需求。

问题:
1、self是啥?
2、怎么在init函数里定义实例属性?

1、什么是self?

  • 在类里面def 函数的时候,默认会在括号里加上一个self。
  • self指的对象本身 ==车在车厂 成为my_car的车
  • 一个对象在类里面 就是self。

2、怎么在init函数里定义实例属性?–对象属性 self对象

实例属性:
1、可以通过实例调用: 在类里面可以通过self调用
2、不可以通过类调用。

问题:初始化的每一车的属性颜色和logo都是一样的。因为在init函数里 属性值写死了?

  • 可能会变化的数据?== 可以定位函数的参数。
  • 设置默认参数 : 可以传 也可以传参 == 跟函数的参数一样的
# 定义类
class Car:
    # 类属性 定义车类的属性
    wheel = True
    engine = True
    def __init__(self,cl="黑色",lg="Tesla"): # 括号里写形参
        self.color = cl  #属性的值进行参数化
        self.logo = lg
        print("正在生产一辆车....")

# 实例化对象
# my_car = Car("红色","Tesla")  # 实例化需要传参
# print(my_car.color)
# print(my_car.logo)

# 有了默认值之后,再实例化对象
your_car = Car(cl="白色")
print(your_car.color)

方法

方法:类里面的函数 特殊叫法。

  • 类方法: 类的行为和动作。不怎么目前不需要掌握。
  • 实例方法: 默认是实例方法 --self,对象本身的动作和行为,最常用的。
    • 只能通过实例调用 不能通过类调用的
  • init函数 : 方法 有点特殊
  • 其他的方法也可以定义。

注意: 实例化对象的时候不会自动调用除了init方法之外的方法。
那么如何调用实例方法呢?–通过实例对象调用。

2、实例方法调用实例属性,self.属性
3、一个实例方法里调用另外一个实例方法?== self.实例方法名字

总结: 定义实例属性的好处,可以说实现所有的实例方法的共享。区别直接定义成某个函数的参数。

  • 实例属性可以让代码使用更加灵活。

问题: 实例属性定义了10个,其中有一部分没有实参,调用的时候,传参有要求吗?–参考函数

# 定义类
class Car:
    # 类属性 定义车类的属性
    wheel = True
    engine = True
    def __init__(self,cl="黑色",lg="Tesla"): # 括号里写形参
        self.color = cl  #属性的值进行参数化
        self.logo = lg
        self.a = "a"  # 相当于一个类属性 值写死了 。
        self.b = "b"
        print("正在生产一辆车....")

    def recharge(self):
        """充电"""
        print("正在充电...")
        print(f"充电的车是{self.color},logo是{self.logo}")

    def driving(self):
        """开车的动作"""
        print("正在开车...")
        print(f"开的车是{self.color},logo是{self.logo}")
        self.recharge()  # 在方法里调用另外一个实例方法: self.方法名字


# 实例化对象
my_car = Car("红色","Tesla")  # 实例化需要传参
print(my_car.color)
print(my_car.logo)

# 调用实例方法  对象.方法
my_car.driving()

# 类调用实例方法 -- 不可以。
# Car.driving()

继承

继承:就是可以直接使用父类的所有方法和属性。

  • 父亲【父类】
  • 儿子【子类】

继承的语法:在括号里写上继承的父类。

  • 子类可以使用父类所有的方法和属性
  • 子类也可以定义自己属性和行为 :
    • 定义自己的方法,并且这个方法里也可以用self调用父类的属性和方法。
  • 子类的方法的名字和父类的方法名字一样的 == 对父类进行重写。【以子类的为准】
  • 父类可以调动子类的方法么?–不可以
class Car:
    wheel = True
    engine = True
    def __init__(self,cl="黑色",lg="Tesla"): # 括号里写形参
        self.color = cl  #属性的值进行参数化
        self.logo = lg
        self.a = "a"  # 相当于一个类属性 值写死了 。
        self.b = "b"
        print("正在生产一辆车....")

    def recharge(self):
        """充电"""
        print("正在充电...")
        print(f"充电的车是{self.color},logo是{self.logo}")

    def driving(self):
        """开车的动作"""
        print("正在开车...")
        print(f"开的车是{self.color},logo是{self.logo}")
        self.recharge()  # 在方法里调用另外一个实例方法: self.方法名字

# 新能源车类
class NewEngergyCar(Car):  # 继承了Car类
    # 定义子类的实例方法
    def save_money(self):
        print("新能源车省钱..")
        # 子类可以调用父类的属性-类里面通过self调用
        print("新能源车的logo是",self.logo,"新能源车的颜色是:",self.color)
        # 调动父类的实例方法
        self.recharge()

    def recharge(self):
        print("新能源车正在充电...")

# 获取一个对象
new_car = NewEngergyCar()
# 对象可以直接调用父类的实例方法
# new_car.driving()


# 调用重写的实例方法
new_car.recharge()

# 对象调动子类自己的实例方法
new_car.save_money()

# 对象可以直接调用父类的实例属性
# print(new_car.logo)

# 对象可以直接调用父类的类属性
# print(new_car.wheel)

# 父类没有办法调动子类的实例方法。 ==--报错:AttributeError: 'Car' object has no attribute 'save_money'
my_car = Car()
my_car.save_money()

运行结果如下:

正在生产一辆车....
新能源车正在充电...
新能源车省钱..
新能源车的logo是 Tesla 新能源车的颜色是: 黑色
新能源车正在充电...
正在生产一辆车....
Traceback (most recent call last):
  File "D:\BaiduNetdiskDownload\1-Python基础\20231117_py65基础第九节课-类和对象\day09_类和对象\d6_类的继承.py", line 69, in <module>
    my_car.save_money()
AttributeError: 'Car' object has no attribute 'save_money'

继承的高级用法

多层继承:爷爷 爸爸 孙子 继承 ,孙子可以获得爷爷 爸爸所有的属性和方法。

多重继承:继承多个爸爸的财产,代码不想写 各种继承父类 。

  • 都写在括号里 中间用逗号隔开就可以了。
  • 所有的父类的方法和属性我都可以直接调用。

总结继承:
1、类的继承写法: 直接在括号里加上父类的名字 可以继承父类的所有方法和属性
2、子类可以定义自己的方法:父类不能使用子类的方法
3、子类重写父类的方法: 子类方法和父类方法重名 会优先只用子类的方法【init最好不要重写】
4、子类可以多层继承和多重继承: 可以使用所有的父类的方法和属性。

class Car:
    wheel = True
    engine = True
    def __init__(self,cl="黑色",lg="Tesla"): # 括号里写形参
        self.color = cl  #属性的值进行参数化
        self.logo = lg
        self.a = "a"  # 相当于一个类属性 值写死了 。
        self.b = "b"
        print("正在生产一辆车....")

    def recharge(self):
        """充电"""
        print("正在充电...")
        print(f"充电的车是{self.color},logo是{self.logo}")

    def driving(self):
        """开车的动作"""
        print("正在开车...")
        print(f"开的车是{self.color},logo是{self.logo}")
        self.recharge()  # 在方法里调用另外一个实例方法: self.方法名字

# 新能源车类
class NewEngergyCar(Car):  # 继承了Car类
    # 定义子类的实例方法
    def save_money(self):
        print("新能源车省钱..")
        # 子类可以调用父类的属性-类里面通过self调用
        print("新能源车的logo是",self.logo,"新能源车的颜色是:",self.color)
        # 调动父类的实例方法
        self.recharge()

    def recharge(self):
        print("新能源车正在充电...")

class Robot:
    def AI(self):
        print("AI语音识别...")

class AutoCar(NewEngergyCar,Robot):
    pass

# 对象
auto_car = AutoCar()
auto_car.save_money()
auto_car.driving()
auto_car.recharge()
auto_car.AI()

运行结果如下:

正在生产一辆车....
新能源车省钱..
新能源车的logo是 Tesla 新能源车的颜色是: 黑色
新能源车正在充电...
正在开车...
开的车是黑色,logo是Tesla
新能源车正在充电...
新能源车正在充电...
AI语音识别...

动态属性 【反射】

动态属性 【反射】:动态的给类和对象添加属性,获取属性,删除属性,修改属性。

    1. 设置属性setattr(对象/类, 属性名,属性值) : 添加属性 ,三个参数: 对象/类, 属性名,属性值 – 重点。
    1. 获取属性getattr (对象/类,属性名):返回属性值;
    • 默认情况下如果属性不存在,会报错;
    • 但是如果传参,不报错 打印参数值
  • 3)删除属性 delattr(对象/类,属性名)
    1. 判断是否存在属性(对象/类,属性名) : 结果是个bool 值
class Car:
    # 类属性 定义车类的属性
    wheel = True
    engine = True
    def __init__(self,cl="黑色",lg="Tesla"): # 括号里写形参
        self.color = cl  #属性的值进行参数化
        self.logo = lg

# 在类外面的设置一个类的属性: 动态属性
setattr(Car,"name","原厂车")
setattr(Car,"name1","原厂车1")
print(Car.name)  # 获取类的属性 :
# 黄色标记原因: 代码静态的时候,不知道类有name属性的; 一定要等代码运行起来时候 才知道有name属性。

# 给对象设置动态属性
my_car = Car()
setattr(my_car,"name","小可爱")
print(my_car.name)

# 获取属性--返回属性值
print(getattr(Car, "body","Not exist"))  # 属性不存在 是否会报错。

# 删除属性 -- 一般来讲 不会直接删除 会先判断是否存在这个属性,然后再删除
# delattr(Car,"wheel1")
# print(Car.wheel)

# 判断是否存在属性 --True存在 False - 不存在
# if hasattr(Car, "wheel"):
#     getattr(Car,"wheel")
#     delattr(Car,"wheel")
# else:
#     setattr(Car,"wheel",True)

setattr(Car,"wheel",True)
print(Car.wheel)

运行结果如下:

原厂车
小可爱
Not exist
True
  • 33
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值