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 二二