@classmethod

基本介绍

  • @classmethod 是 Python 中的一个装饰器,作用是把一个方法封装成类方法 。

  • 类方法是什么,就是可以直接使用类,无需实例化调用的方法叫做类方法。

  • 比如:

  • class DateUtils:    
        @classmethod
        def get_time(cls):
            import datetime
            return datetime.datetime.now()
     
    #类调用
    year1 = DateUtils.get_time
    print(year1)
    
    #实例化后调用
    date = DateUtils()
    year2 =n date.get_time
    print(year2)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39



    # `@model_validator`(mode="")(pydantic库)

    ## 可输入参数:

    * `before`和`after`

    * 区别如下:

    - `@model_validator(mode="before")` 在`pydantic`模型进行内置类型和约束验证前执行 ,处理的是原始输入数据,通常为字典形式。可以对数据进行转换,如将字符串转为数字,还能进行数据清理等操作,之后返回处理过的字典供后续验证。比如输入的日期是多种字符串格式,可在`before`验证中统一转换为指定日期格式。

    - `@model_validator(mode="after")` 在模型完成内置验证后执行,此时面对的是已经初步验证通过的模型实例对象,不能对数据来源进行转换,但能基于完整的实例对象做进一步检查。

    - 通俗地来说`@model_validator`中参数为`before`时该模型中的检查方法更倾向于对输入格式的检查和转换

    - 而后者,即参数为`after`的时候,更加倾向于在数据格式都毫无疑问的时候,单纯对数据大小关系进行检查,其重点没有放在格式上面,而是数值关系,所以叫`after`。

    ```python
    from pydantic import BaseModel, model_validator

    class TimeInterval(BaseModel):
    start_time: int
    end_time: int

    @model_validator(mode="after")
    def check_time_order(cls, instance):
    if instance.start_time >= instance.end_time:
    raise ValueError("开始时间必须早于结束时间")
    return instance

    # 测试
    try:
    time_data = {"start_time": 1672531200, "end_time": 1672534800}#直接验证数值大小
    time_interval = TimeInterval(**time_data)
    print(time_interval)
    except ValueError as e:
    print(f"验证失败: {e}")

@property

基本介绍

  • python @property 装饰器使一个方法可以像属性一样被使用,而不需要在调用的时候带上()
    可参阅该博客:@property

  • 举例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Person():

    def __init__(self, firstname, lastname):
    self.first = firstname
    self.last = lastname
    self.fullname = self.first + ' '+ self.last

    def email(self):
    return '{}.{}@email.com'.format(self.first, self.last)

    实例化操作:

    1
    2
    person = Person(zhang,san)
    #print......

    这里若是这样操作:

    1
    person.lastname = "si"

    person.fullname则仍然是曾经的zhang,shan
    因为person.fullname仍然是曾经的定义,没有被改变,我们需要使用修改值的函数去修改该变量的值。
    如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 将fullname属性,改为fullname()方法
    # 但是对于没有使用fullname()方法的旧代码,可以就没办法使用person.fullname的方式调用了
    # 所以这样更改后,要修改所有的旧代码
    class Person():
    def __init__(self, first_name, last_name):
    self.first = first_name
    self.last = last_name

    def fullname(self):
    return self.first + ' ' + self.last

    def email(self):
    return '{}.{}@email.com'.format(self.first, self.last)


    person = Person('zhang', 'san')
    print(person.fullname())


    person.last = 'si'

    print(person.fullname())

    这样我们需要print(person.fullname())才可以输出新的值,但是这会很麻烦,我们可以使用@property进行修饰,简化对方法的修饰。
    比如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    # 添加@property属性,可以在不改变原有调用规则的基础上,获得正确的fullname
    class Person():
    def __init__(self, first_name, last_name):
    self.first = first_name
    self.last = last_name

    @property
    def fullname(self):
    return self.first + ' ' + self.last

    def email(self):
    return '{}.{}@email.com'.format(self.first, self.last)

    # 初始化一个Person对象
    person = Person('zhang', 'san')
    print(person.fullname)

    # 修改last_name
    person.last = 'si'
    print(person.fullname)

    #输出结果
    zhang san
    zhang si

    我们就可以简单调用方法了。