Python Note -- Day 13. 面向对象 - 高阶

本文详细介绍了Python面向对象编程的概念,包括类的内置成员、方法的分类(对象方法、类方法、绑定类方法和静态方法)、常用函数(如issubclass、isinstance、hasattr等)以及魔术方法的使用,如__init__、__del__、__new__等。通过实例展示了如何在不同场景下使用这些特性,帮助读者深入理解Python的面向对象编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

19 面向对象 — 高阶

19.1 内置成员

class A():
    pass
class C():
    pass
class B(C):
    pass
class Demo(A,B):
    '''
    此处是类的文档说明
    '''
    name = "XX"
    age = 30
    def sing(self):
        print('the songs rhythm and melody')
    pass

obj = Demo()

# 获取类/对象的所属成员
res = Demo.__dict__    # {'__module__': '__main__', 'name': 'XX', 'age': 30, 'sing': <function Demo.sing at 0x00000000021BA1F8>, '__dict__': <attribute '__dict__' of 'Demo' objects>, '__weakref__': <attribute '__weakref__' of 'Demo' objects>, '__doc__': None}
ree = obj.__dict__     # {}  当前对象没有属于自己的属性
obj.music = 'one'
ree = obj.__dict__     # {'music': 'one'}
print(ree)

# 获取类的文档说明   类/对象.__doc__
res = Demo.__doc__
res = obj.__doc__

# 获取类名称组成的字符串
res = Demo.__name__

# 获取类所在的文件名称,如果是当前文档,显示为__main__
res = Demo.__module__

# 获取当前类的父类列表 bases
res = Demo.__bases__   # (<class '__main__.A'>, <class '__main__.B'>)
res = Demo.__base__    # 获取继承的第一个父类  <class '__main__.A'>

# 获取当前类的继承链  MRO列表 
res = Demo.mro()    # [<class '__main__.Demo'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>]

19.2 方法的分类

19.2.1 对象方法

特征:
1.类中定义的方法,含有self参数
2.含有self的方法,只能使用self进行调用
3.该方法会把调用的对象传进来

class Demo():
    # 对象方法
    def f1(self):
        print('this is f1')
# 实例化对象
o = Demo()
o.f1()
# 不能直接使用类调用 对象方法,除非传递一个对象,不推荐
Demo.f1('a')

19.2.2 类方法

特征:
1.在类中的方法,使用装饰器 @classmethod 进行了装饰
2.方法中有 cls形参
3.不需要实例化对象,直接使用类进行调用
4.会把调用这个方法的类传递进来

class Demo():
    # 类方法
    @classmethod
    def f2(cls,a):
        print(cls,a)
        print('this is class function f2')
obj = Demo()
Demo.f2('')
obj.f2('')   # 即便使用对象调用,传递进去的依然是类
# <class '__main__.Demo'>
# this is class function f2

19.2.3 绑定类方法

特征:
1.类中定义的方法,没有任何参数
2.只能使用类进行调用
3.不会传递对象或者类进来

class Demo():
    # 绑定类方法
    def f3():
        print('this is bind class function f3')

Demo.f3()
# 不能使用对象调用

19.2.4 静态方法

特征:
1.类中定义的方法,使用了 装饰器 @staticmethod 进行了装饰 
2.可以使用对象或者类进行调用 
3.不会传递对象或类进来

class Demo():
    # 静态方法
    @staticmethod
    def f4():
        print('this is static function f4')
    @staticmethod
    def f5(a,b):
        print(a,b)
        print('this is static f5')
Demo.f4()
o = Demo()
o.f4()
Demo.f5(3,4)
o.f5(6,7)

19.3 常用函数

19.3.1 检测类和对象相关

  • issubclass(子类,父类) 检测一个类是否为另一个类的子类
res = issubclass(B,C)
print(res)
  • isinstance(对象,类) 检测一个对象是否是指定类或指定类的子类的实例化
class A():
    pass
class B(A):
    pass
class C(A):
    pass
class D(B,C):
    pass

a = A()
b = B()
d = D()
res = isinstance(d,A)
print(res)   # True
  • hasattr(对象/类,'成员名称') 检测类/对象是否包含指定名称的成员
class A():
    age = 20
    _one = ''
class B(A):
    pass
class C(A):
    pass
class D(B,C):
    name = ''
    _sex = ''
    __age = 20
    def say(self):
        print('say sth')

a = A()
b = B()
d = D()
res = hasattr(d,'age')  # True
res = hasattr(B,'age')  # True
res = hasattr(d,'say')  # True
res = hasattr(d,'__age')  # False 私有成员 注意!
res = hasattr(d,'_sex')  # True
res = hasattr(d,'_one')  # True

19.3.2 操作类和对象相关

  • getattr(类/对象,'成员名') 获取类/对象的成员的值,除了私有成员
class A():
    age = 20
    _one = 'two'
class B(A):
    pass
class C(A):
    pass
class D(B,C):
    name = ''
    _sex = ''
    __age = 18
    def say(self):
        print('say sth')

a = A()
b = B()
d = D()
res = getattr(d,'_one')  # two
res = getattr(d,'say')   # <bound method D.say of <__main__.D object at 0x00000000023CF388>>
print(res)
  • setattr(对象/类,'成员名','成员值') 可以设置对象/类的成员的属性值
setattr(d,'name','ll')
print(d.name) 
  • delattr() 删除对象/类的成员,和 del 直接删除对象的成员是一样的
print(d.age) # 20
delattr(A,'age')
print(d.age) # error, no attribute
  • dir() 获取当前对象所有可以访问的成员的列表
    print(dir(d))

19.4 魔术方法

19.4.1 类相关魔术方法

不需要手动调用就可自动执行的方法

1. __init__ 初始化方法
    触发机制:当实例化对象后,就会立即触发的方法
    作用:为当前创建的对象,完成一系列初始化的操作。如,成员属性的赋值,方法的调用,打开或创建一些资源等
    参数:一个self,接收当前对象,其他参数根据需求定义
    返回值: 无
    注意事项: 无
    
2. __del__ 析构方法
    触发机制:当该类对象被销毁时,自动触发
    作用: 关闭或释放在对象创建时打开或创建的一些资源
    参数: 一个self,接收当前对象
    返回值:无
    注意事项:无

3. __new__ 构造方法
    触发机制: 实例化对象时,自动触发(在__init__之前触发)
    作用:    管理控制对象创建的过程
    参数:    一个cls,接受当前类,其他参数根据初始化方法的参数进行决定
    返回值:  必须返回object.__new__(cls)进行对象的创建,若无返回值,则实例化对象的结果为None
    注意事项: 
        1. __new__方法的参数和__init__的参数保持一致,除了第一个参数
        2. 必须返回object.__new__(cls)进行对象的创建,若无返回值,则实例化对象的结果为None
    应用场景:设计模式中的单例设计模式

class Person():

    # 构造方法
    def __new__(cls, *args):
        print('触发构造方法')
        print(args)
        # 若在该方法中没有返回对象(如下格式),则对象无法创建,实例化对象后返回如下结果:
        # 触发构造方法
        # ('zhang', 55, 'male')

        return object.__new__(cls)

    # 初始化方法
    def __init__(self,name,age,sex):
        print('触发初始化方法')
        self.name = name
        self.age = age
        self.sex = sex

    # 析构方法
    def __del__(self):
        print('触发析构方法')

# 实例化对象
one = Person('zhang',55,'male')
# 触发构造方法
# ('zhang', 55, 'male')
# 触发初始化方法
# 触发析构方法

4.__call__
    触发机制: 把对象当作函数直接调用时,自动触发
    作用:   一般用于归纳类或对象的操作步骤,方便调用
    参数:  一个self,接受对象,其他根据需求
    返回值: 可有可无

5.__len__
    触发机制: 当时有len函数去检测当前对象的时候,自动触发
    作用:    可以使用len函数检测当前对象某个数据的信息
    参数:    一个self
    返回值:  必须是一个整型
    注意事项: len要获取什么属性的值,就在返回值中返回哪个属性的长度即可

class Demo():
    alist = [1,2,3]
    
    # 可以代替对象使用len函数,并返回一个指定的整型
    def __len__(self):
        return len(self.alist)
one = Demo()
res = len(one)
print(res)

6.__str__
    触发机制: 当使用str或者print函数对对象进行操作时,自动触发
    作用:   代替对象进行字符串的返回,可以自定义打印的信息
    参数:  一个self
    返回值: 必须是字符串类型
    注意事项:该方法中 return 的内容 自行决定

class Demo():
    alist = [1,2,3]

    # 可以代替对象进行str或print的字符串信息返回
    def __str__(self):
        return 'whatever and wherever str'
one = Demo()
res = str(one)
print(res)  # # whatever and wherever str
print(one)  # whatever and wherever str

7.__repr__
    触发机制:使用repr方法对当前对象进行转换时自动触发
    作用:  可以设置repr函数操作对象的结果
    参数:  一个self
    返回值: 必须是字符串类型
    注意事项:正常情况下,若没有__str__这个魔术方法,__repr__就会代替其执行

8.__bool__
    触发机制: 当前使用bool函数转换对象时,自动触发。默认情况下,对象会转为True
    作用:    可以代替对象进行bool类型转换,可以转换任何数据
    参数:    一个self
    返回值:  必须是一个bool类型的返回值

class Demo():
    alist = [1,2,3]
    def __bool__(self):
        return bool(self.alist)

one = Demo()
res = bool(one)
print(res)

* str和repr 以及对应魔术方法的区别

1.str 和 repr函数都可以把其他类型的值专为字符串
2.若数据对象没有更明显的区别,二者结果是一样的

1.str函数会把对象转为 更适合阅读的形式
2.repr函数会把对象转为 解释器 读取的形式

n = 3398
r1 = str(n)
r2 = repr(n)
print(r1,type(r1))
print(r2,type(r2))
# 3398 <class 'str'>
# 3398 <class 'str'>

n = '398'
r1 = str(n)
r2 = repr(n)
print(r1,type(r1))
print(r2,type(r2))
# 398 <class 'str'>
# '398' <class 'str'>

19.4.2 成员相关魔术方法

1.__getattribute__
    触发机制: 把访问对象成员时,自动触发,无论对象成员是否存在
    作用:   可以在获取对象成员时,对数据进行一些处理
    参数:  一个self接受对象,一个item接收当前访问的成员名称
    返回值: 可有可无,返回的值就是访问的结果
    注意事项:在当前魔术方法中,禁止对当前对象的成员进行访问,会触发递归
            若想要在当前方法中访问成员,必须使用 object.__getattribute__(self,item)
            
2. __getattr__
    触发机制:当访问对象中不存在的成员时,自动触发
    作用:    防止访问不存在的成员时报错,也可以为不存在的成员进行赋值操作
    参数:  一个self接受对象,一个item接收当前访问的成员名称
    返回值: 可有可无
    注意事项:当存在__getattribute__时,会去执行此方法
    
3. __setattr__
    触发机制:给对象成员进行赋值时,自动触发,包括修改、添加
    作用:    可以限制或管理对象成员的添加和修改操作
    参数:  1.self接受对象  2.设置的成员名称  3.设置的成员值
    返回值:  无
    注意事项:在当前方法中 禁止给当前对象成员直接进行赋值操作,否则会触发递归
            若想要赋值,使用 object.__setattr__(self,key,val)
            
4. __delattr__
    触发机制:删除对象成员时,自动触发
    作用:    可以限制对象成员的删除,还可以防止在删除不存在成员时报错
    参数:  1.self接受对象  2.删除的成员名称 
    返回值: 无
    注意事项: 当前方法中,禁止直接删除对象成员,会触发递归
            若要删除,使用 object.__delattr__(self,item)

  • try: except
class Person():
    name = 'zhang'
    age = 40
    sex = 'male'

    def __init__(self,n,a,s):
        self.name = n
        self.age = a
        self.sex = s

    def say(self):
        print('make a speech')

    # 获取对象成员时,自动触发
    def __getattribute__(self, item):
        # print(self.name)  不允许此操作,会报错

        # 判断是否存在属性,注意!!
        # try:
            res = object.__getattribute__(self,item)
            # 方法中可以对访问的成员数据进行处理
            return res[0]+'**'+res[-1]
        # except:
        #     return False

    # 当访问不存在的成员时,自动触发
    def __getattr__(self, item):
        print(item)
        return False

    def __setattr__(self, key, value):
        print(self,key,value)
        object.__setattr__(self,key,value)

    def __delattr__(self, item):
        print(item)

z = Person('zhangs',45,'male')
print(z.one)
z.one = 'this is new'
print(z.one)
del z.one

访问成员调用顺序 !!!

1.__getattribute__
2.数据描述符
3.调用当前对象的成员
4.调用当前类的成员
5.非数据描述符
6.调用父类的成员
7.__getattr__

  • 以上步骤是调用某个成员的顺序,前面的能够调用成功,后面的就不再执行

数据描述符:同时具备三个魔术方法的类就是
非数据描述符:不同时具备

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值