Python中的魔术方法大全

目录:

1.__init__初始化方法

2.__new__构造方法

3.__del__析构方法

4.__call__方法

5.__len__方法

6.__str__方法

7.__repr__方法

8.__bool__方法

9.__format__方法

属性相关魔术方法

10.__getattribute__方法

11.__getattr__方法

12.__setattr__方法

 

魔术方法

一种特殊的方法而已

特点

不需要人工调用,在特定时刻自动触发执行

魔术方法种类

1.__init__初始化方法*******

触发时机:实例化对象之后触发
作用:为对象添加对象的所属成员
参数:self,接收当前对象,其他的参数根据实例化的传参决定
返回值:无
注意事项:无

# _author:"Ma ren"
# date: 2023/2/23

# __init__:初始化魔术方法

class Human:
    # 属性
    name = '张三'
    age = 18
    gender = 'male'
    skin = 'yellow'

    # 方法
    def __init__(self,name,gender,age):  # name是__init__的形参
        print('__init__方法被执行')
        # print(self)
        # 为对象添加成员
        self.name = name   # self.name中的name是对象的成员
        self.gender = gender
        self.age = age


    def eat(self):
        print('吃饭方法')

    def run(self):
        print('跑步方法')

    def sleep(self):
        print('睡觉方法')

# 实例化一个人的对象
h1 = Human('lxx','male',18)   #<1.制作一个对象,2.为对象初始化操作>
print(h1.__dict__)  # 打印对象成员
View Code

2.__new__构造方法

触发时机:实例化对象的时候触发
作用:管理控制对象的生成过程
参数:一个cls接收当前类,其他的参数根据实例化的参数决定
返回值: 可有可无 没有返回值 实例化结果为None
注意事项:__new__魔术方法跟__init__的魔术方法参数一致(除了第一个)

# _author:"Ma ren"
# date: 2023/2/23

# __new__构造方法

class Human:
    # 属性
    name = '张三'
    age = 18
    gender = 'male'
    skin = 'yellow'

    # 方法
    # 魔术方法
    def __new__(cls, *args, **kwargs):
        # print('__new__方法被触发')
        # return 2
        # 自己控制对象的生成(女的生,男的不生)
        # print(args)
        if '' in args:
            # 不生成对象
            pass
        else:
            # 生成对象且返回
            return object.__new__(cls)  # object上帝之手


    def eat(self):
        print('吃饭方法')

    def run(self):
        print('跑步方法')

    def sleep(self):
        print('睡觉方法')


h1 = Human('')   # 实例化对象【1.制作一个对象(new),2.初始化对象】
print(h1)

# 利用__new__方法来一个狸猫换太子
# _author:"Ma ren"
# date: 2023/2/23


class  Monkey:
    pass


class Human:
    def __new__(cls, *args, **kwargs):
        return object.__new__(Monkey)
    pass


# 看似使用人类造对象,实际却生成了一个猴子对象
human_obj = Human()
print(human_obj)
View Code

3.__del__析构方法

触发时机:对象被系统回收的时候触发
作用:回收系统使用过程中的信息和变量
参数:一个self接收当前对象
返回值:无
注意事项:无

# _author:"Ma ren"
# date: 2023/2/23

# __del__魔术方法

class Human:
    # 属性
    name = '张三'
    age = 18
    gender = 'male'
    skin = 'yellow'

    # 方法


    def eat(self):
        print('吃饭方法')

    def run(self):
        print('跑步方法')

    def sleep(self):
        print('睡觉方法')

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

h = Human()
print(h)

# 主动删除对象
del h  # 删除对象,系统回收对象
print('=================')
View Code

4.__call__方法

触发时机:将对象当做函数调用的时候自动触发
作用:常用语归结/对象的操作步骤,方便后期调用
参数:一个self接收当前对象,其余的参数根据需求添加
返回值:可以有,也可以没有
注意事项:无

# _author:"Ma ren"
# date: 2023/2/25


# # 声明一个类
# class Human:
#     # 成员属性
#     name = '张三'
#     gender = 'famale'
#     age = 18
#
#     # 成员方法
#     # 魔术方法
#     def __call__(self, *args, **kwargs):
#         print('__call__方法被触发')
#
#     def eat(self):
#         print('吃的方法')
#
#     def cry(self):
#         print('55555555555~~~~')
#
#
# # 实例化一个对象
# zs = Human()
# print(zs)
#
# # 对象能够加()调用吗?一般情况下是不行的
# zs()

# __call__方法的作用

# 以制作蛋糕为例子
class MakeCake:
    # 和面
    def huomian(self):
        print('和面')
    # 发酵
    def fajiao(self):
        print('发酵')
    # 烘烤
    def hongkao(self):
        print('烘烤')
    # 切型
    def qiexing(self):
        print('切型')
    # 抹奶油
    def monaiyou(self):
        print('抹奶油')
    # 加水果
    def jiashuiguo(self):
        print('加水果')
    # 打包
    def dabao(self):
        print('打包')

    # 封装成一个函数
    # def getCake(self):
    #     self.huomian()
    #     self.fajiao()
    #     self.hongkao()
    #     self.qiexing()
    #     self.monaiyou()
    #     self.jiashuiguo()
    #     self.dabao()

    # 更进一步,封装成__call__方法
    def __call__(self):
        self.huomian()
        self.fajiao()
        self.hongkao()
        self.qiexing()
        self.monaiyou()
        self.jiashuiguo()
        self.dabao()

mc1 = MakeCake()

# 如果每次都这样调用制作蛋糕的方法,比较繁琐,考虑将这些步骤封装到一个方法中
# mc1.huomian()
# mc1.fajiao()
# mc1.hongkao()
# mc1.qiexing()
# mc1.monaiyou()
# mc1.jiashuiguo()
# mc1.dabao()

# mc1.getCake()
mc1() 
View Code

5.__len__方法

触发时机:使用len函数检测对象的时候,自动触发
作用:使用len可以检测对象中某个数据的信息
参数:一个self,接收当前对象
返回值:必须要有,必须是整型
注意事项:无

# _author:"Ma ren"
# date: 2023/2/25

# 声明一个类
class Car:
    # 成员属性
    color = 'black'
    wight = '2t'
    grand = 'BYD'
    wheel = ['左前轮','右前轮','左后轮','右后轮','备胎']


    # 成员方法
    # 魔术方法
    def __len__(self):
        print('__len__方法被触发')
        res = len(self.wheel)
        return res

    def playmusic(self):
        print('你存在我深深的脑海里')

    def move(self):
        print('请注意倒车,请注意倒车')

# 实例化一个对象
car = Car()

# 可以使用len函数检测对象吗?
res = len(car)
print(res)
View Code

6.__str__方法

触发时机:使用print打印对象的时候自动触发
作用:可以定义打印对象显示的信息内容
参数:一个self,接收当前对象
返回值:必须要有,必须是字符串类型
注意事项:除了print之外,使用str()转换数据的时候,也会触发

# _author:"Ma ren"
# date: 2023/2/25

class Human:

    # 成员属性
    color = 'yellow'
    gender = 'female'
    name = 'wuudd'
    age = 18

    # 成员方法
    # 魔法方法
    def __str__(self):
        return self.name


    def eat(self):
        print('正向')

    def smile(self):
        print('hahhhahhah')

l = list([1,2,3,4])
print(l)

h = Human()
print(h)

# 触发__str__的第二个时机
str(h)
View Code

7.__repr__方法

触发时机:再使用repr转换对象的时候自动触发
作用:可以设置repr函数操作对象的结果
参数:一个self,接收当前对象
返回值:必须要有,必须是字符串类型
注意事项:正常情况下,类中的__str__和__repr__魔术方法是完全一致的.字符串中的str和repr方法是不一样的。

# _author:"Ma ren"
# date: 2023/2/25

class Human:
    # 属性
    color = 'yellow'
    name = 'egon'
    age = 18
    gender = 'male'

    # 方法
    # 魔术方法   在通常类中,repr方法重载相当于str方法被重载
    def __repr__(self):
        print('__repr__方法被触发')

    # 所有类都默认存在一个等式
    # __str__ = __repr__  # 将__repr__方法赋值给__str__方法,完全一样

    def eat(self):
        print('真好吃')

    def drink(self):
        print('真好喝水')

# h = Human()
# print(h)

# repr的使用
my_song = '我\n喜欢\t你'
print(my_song)   # 打印字符串对象
print(str(my_song))
print(repr(my_song))
View Code

8.__bool__方法

触发时机:使用bool()转换对象的时候自动触发
作用:用户检测对象成员的信息
参数:一个self,接收当前对象
返回值:必须要有,必须是布尔值
注意事项:无

# _author:"Ma ren"
# date: 2023/2/25

class Human:

    # 成员属性
    name = 'tank'
    age = 18
    gender = 'male'
    color = 'yellow'
    married = '未婚'


    # 成员方法
    # 添加一个魔术方法__bool__
    def __bool__(self):
        print('__bool__方法被触发')
        # 根据某些数据返回不同的布尔值,实现布尔转换对象的作用
        if self.married == '已婚':
            return True
        else:
            return False

    def smoking(self):
        print('反向抽烟')


    def say(self):
        print('甜言蜜语')

h = Human()
print(h)


# 转换对象  检测男人对象是否已婚
res = bool(h)
print(res)
View Code

9.__format__方法

触发时机:使用bool()转换对象的时候自动触发
作用:用户检测对象成员的信息
参数:一个self,接收当前对象
返回值:必须要有,必须是布尔值
注意事项:无

# _author:"Ma ren"
# date: 2023/2/25

class Girl:
    # 成员属性
    name = '阿道夫'
    age = 18
    gender = 'female'

    # 成员方法
    # 添加魔术方法__format__
    def __format__(self, format_spec):
        # print('__format__方法被触发')
        # print(format_spec)  # format-spec接收的是限定符号的字符串
        # return self.name

        # 实现format自带的对齐和填充功能
        # 1.接收限定符号
        flag = format_spec
        print(flag)
        # 2.拆分限定符号
        fillchar = flag[0] # 填充字符
        align = flag[1]    # 对齐方式
        length = int(flag[2:]) # 长度
        print(fillchar,align,length)
        # 3.根据不同的符号进行不同的操作
        # 判断对齐方式
        if align == '>':  # 右对齐
            newname = self.name.rjust(length,fillchar)
        elif align == '^':  # 居中对齐
            newname = self.name.center(length,fillchar)
        elif align == '<': # 左对齐
            newname = self.name.ljust(length,fillchar)
        return newname


    def shopping(self):
        print('买买买')

    def eating(self):
        print('吃吃吃')


girl = Girl()
print(girl)

# 使用format来操作对象
action = '我和我的闺蜜{:@^20}去逛街'
# res = action.format('静静')
res = action.format(girl)
print(res)
View Code

 
属性相关魔术方法

获取成员,删除成员,修改成员相关联的魔术方法
总共有5个

1.__getattr__
2.__setattr__
3.__delattr__
4.__getattribute__
5.__dir__

属性访问的顺序:
1.__getattribute__
2.调用数据描述符
3.调用当前对象的所属成员
4.调用类的所属成员
5.调用非数据描述符
6.调用父类的所属成员
7.调用__getattr__

注意:以上步骤就是调用某个成员的访问顺序及优先级,前面能够找到,就不会再向后查找

10.__getattribute__方法

触发时机:访问对象成员的时候,就会触发,无论成员是否存在
作用:用户获取数据的时候,进行数据处理操作
参数:一个self,接收当前对象。参数item接收的是访问对象成员名称的字符串。
返回值:有,不设置返回值的时候,返回None
注意事项:在当前魔术方法中,禁止使用当前对象.成员的方式访问成员,否则会触发递归操作,必须借助object.__getattribute__来获取当前成员。

# _author:"Ma ren"
# date: 2023/2/26

class Human:
    # 成员属性
    def __init__(self):
        self.name = 'egon'
        self.gender = 'male'
        self.age = 18

    # 成员方法

    # 添加魔术方法
    def __getattribute__(self, item):
        """
        :param item: 所访问的成员属性名称
        :return:
        """
        # print('__getattribute__方法被触发')
        # print(item)
        # 注意,一定不能使用当前对象的成员访问,会再次触发当前魔术方法进入递归循环
        res = object.__getattribute__(self,item)
        # 隐藏用户名
        new_name = res[0] + '*' + res[-1]
        return new_name

    def eat(self):
        print('我是eat方法')

    def drink(self):
        print('我是drink方法')

# 实例化对象
h = Human()
print(h)

# 访问对象的名称
print(h.name)
View Code

11.__getattr__方法

触发时机:访问不存在的对象成员的时候自动触发
作用:防止访问不存在的成员的时候报错!为不存在的成员定义值
参数:self,接收当前对象,第二个参数item,接收的是访问成员的名称字符串
返回值:可有可无,不设置返回值的时候,返回None
注意事项:在当前魔术方法中,禁止使用当前对象.成员的方式访问成员,否则会触发递归操作,必须借助object.__getattribute__来获取当前成员。

# _author:"Ma ren"
# date: 2023/2/26

class Human:
    def __init__(self):
        self.name = 'takn'
        self.gender = 'male'
        self.age = 18

    # 成员方法
    # 添加魔术方法
    def __getattr__(self, item):
        print('__getattr__被触发')
        print(item)
        return 4444


    def eat(self):
        print('eat方法')

    def drink(self):
        print('drink方法')

h = Human()
# print(h)
# print(h.gender)
print(h.gender1)
View Code

12.__setattr__方法

触发时机:添加对象成员或者修改对象成员的时候自动触发
作用:可以限制或者管理对象的添加与修改操作
参数:self,接收当前对象,第二个参数key,接收的是访问成员的名称字符串,第三个参数value,是设置或者添加的成员的值对应的字符串
返回值:无
注意事项:在当前魔术方法中,禁止使用 当前对象.成员 的方式访问成员,否则会触发递归操作,必须借助object.__setattr__来获取当前成员。

# _author:"Ma ren"
# date: 2023/2/26

class Human:
    def __init__(self):
        self.name = 'tnk'
        self.gender = 'male'
        self.age = 18


    # 成员方法

    # 魔术方法
    def __setattr__(self, key, value):  # 相当于在重载object中的__setattr__方法
        # print(key,value)
        # 禁止修改性别,名称最多3个字符
        # super.__setattr__(self,key,value)
        if key == 'gender':
            pass
        elif key == 'name':
            if len(value) > 3:
                pass
            else:
                object.__setattr__(self,key,value)
        else:
            object.__setattr__(self,key,value)
        # print('__setattr__被触发')


    def eat(self):
        print('eat方法')

    def drink(self):
        print('drink方法')


h = Human()
print(h.__dict__)

# 修改对象成员
h.name = 'egon'
print(h.__dict__)
View Code

 

posted @ 2023-02-23 22:48  五仁味儿月饼  阅读(169)  评论(0编辑  收藏  举报