python内置装饰器

python内置装饰器

内置装饰器

  • 不用实例化、直接调用
  • 提升代码的可读性
    内置装饰器:classmethod类方法、staticmethod静态方法

普通方法

  • 定义:第一个参数为self,代表 实例本身
  • 调用:要有实例化的过程,通过 实例对象.方法名 调用
'''普通方法'''
#1. 定义
class MethodsDemo:
    param_a = 0 #类变量
    def normal_demo(self): # 定义一个类方法,第一个参数必须为self
      print("这是一个普通方法", self.param_a)

#2. 调用
md = MethodsDemo()
md.normal_demo()

输出结果为:这是一个普通方法 0

类方法

  • 定义:
  • 使用 @classmethod 装饰器,第一个参数为类本身,所以通常使用cls命名做区分(非强制)
    - 在类内可以直接使用类方法或类变量,无法直接使用实例变量或方法
  • 调用:无需实例化,直接通过 类.方法名 调用,也可以通过 实例.方法名 调用
''类方法'''
#1. 类的定义
class MethodsDemo:
    param_a = 0
    # 定义类方法必须加 classmethod装饰器
    @classmethod
    def classmethod_demo(cls):
        """
        类方法,第一个参数需要改为cls
        :return:
        """
        print("类方法", cls.param_a)
#2. 类的调用
MethodsDemo.classmethod_demo() #无需实例化,直接调用

输出结果为:类方法 0
调用普通方法一定要实例化

class MethodsDemo:
    CLASS_PARAM = 0

    def demo_method(self):  #实例方法
        print("这是一个普通方法")

    @classmethod
    def class_method(cls):
        print("这是一个类方法",cls.CLASS_PARAM)

#调用
MethodsDemo.class_method() #类方法可以直接调用
MethodsDemo.demo_method() #报错,实例化方法不可直接调用,需要实例化

输出结果为:
这是一个类方法 0
TypeError: MethodsDemo.demo_method() missing 1 required positional argument: ‘self’
实例化方法内,可以直接调用实例化方法
类方法内,不可以直接调用实例方法、实例变量;可以直接调用类方法、实例变量

class MethodsDemo:
    CLASS_PARAM = 0
    def __init__(self):  #初始化方法
        self.a = 'abc'
    def demo_method(self):  #实例方法
        print("这是一个普通方法")
    def demo_method2(self):
        self.demo_method() #实例化方法内,可以直接调用实例化方法
        print("这是一个普通方法2")
    @classmethod
    def class_method(cls):
        #cls.demo_method() #类方法内,不可以直接调用实例方法,TypeError: MethodsDemo.demo_method() missing 1 required positional argument: 'self'
        #cls.a  #类方法内,不可以直接调用实例变量,AttributeError: type object 'MethodsDemo' has no attribute 'a'
        print("这是一个类方法",cls.CLASS_PARAM)

    @classmethod
    def class_method2(cls):
        cls.class_method() #类方法内,可以直接调用类方法,实例变量
        print("这是一个类方法2",cls.CLASS_PARAM)

#调用
a1 = MethodsDemo()
a1.demo_method2()
#MethodsDemo.class_method()
MethodsDemo.class_method2()

输出结果为:
这是一个普通方法
这是一个普通方法2
这是一个类方法 0
这是一个类方法2 0

静态方法

  • 定义:
  • 使用 @staticmethod 装饰器,没有和类本身有关的参数
  • 无法直接使用任何类变量、类方法或者实例方法、实例变量
  • 调用:无需实例化,直接通过 类.方法名 调用,也可以通过 实例.方法名 调用
class MethodsDemo:
    param_a = 0
    @staticmethod #静态方法定义:1、要使用staticmethod装饰器 2、这个方法是没有self、或者cls
    def static_demo():
        print("静态方法") #无法直接调用类变量
#调用
MethodsDemo.static_demo()
a = MethodsDemo()
a.static_demo()

输出结果为:
静态方法
静态方法

普通方法、类方法、静态方法

在这里插入图片描述

实际案例

  • 右边的代码实现的需求是格式化输出时间
  • 如果现在需求变更,输入 年、月、日 没法保证格式统一,可能是json,可能是其他格式的字符串,在不修改构造函数的前提下,如何更改代码
class DateFormat:
    def __init__(self, year=0, month=0, day=0):
        self.year = year
        self.month = month
        self.day = day
    def out_date(self):
        return f"输入的时间为{self.year}年,{self.month}月,{self.day}日"

def json_format(json_data):
    year,month,day=json_data['year'],json_data['month'],json_data['day']
    # print(year,month,day)
    return year,month,day
print(json_format({"year":2021,"month":12,"day":24}))

year, month, day = json_format({"year":2021,"month":12,"day":24})
demo = DateFormat(year, month, day)
print(demo.out_date())

输出结果为:
(2021, 12, 24)
输入的时间为2021年,12月,24日

class DateFormat:
    def __init__(self, year=0, month=0, day=0):
        self.year = year
        self.month = month
        self.day = day
    def out_date(self):
        return f"输入的时间为{self.year}年,{self.month}月,{self.day}日"

    @classmethod
    def json_format(cls,json_data):
        '''输入一个字典格式的数据信息,返回(2021, 12, 24)'''
        year, month, day = json_data['year'], json_data['month'], json_data['day']
        return cls(year,month,day)
json_data ={"year":2021,"month":12,"day":24}
#使用json格式化,生成想要的日期格式,返回DateFormat实例
demo = DateFormat.json_format(json_data)
print(demo.out_date())

输出结果为:
输入的时间为2021年,12月,24日

静态方法实际案例

此方法没有任何和实例、类相关的部分,可以作为一个独立函数使用
某些场景下,从业务逻辑来说又属于类的一部分
例子:比赛

'''多轮比赛,每轮由两个不同的英雄对打'''
class Game:
    def __init__(self,first_hero,second_hero):
        self.first_hero = first_hero
        self.second_hero = second_hero
    #fight 有和实例变量交互的部分,所以需要定义为一个普通方法
    def fight(self):
        print(f"本来比赛开始,由{self.first_hero} VS {self.second_hero}")
    #start 没有和类和实例交互的部分,那么就可以使用staticmethod
    @staticmethod
    def start():
        print("游戏开始")

Game.start()
game1 =Game("11","22")
game2 =Game("一一","二二")
game1.fight()
game2.fight()

输出结果为:
游戏开始
本来比赛开始,由11 VS 22
本来比赛开始,由一一 VS 二二

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值