Notas de Python 05 (uso de decoradores)

El uso de un decorador (@property)

@propertyEs un decorador utilizado para crear propiedades en Python. Su función es convertir un método de clase en una propiedad de clase, de modo que  se pueda acceder al método como una propiedad sin utilizar la sintaxis de una llamada de función. Los principales beneficios de su uso @propertyson los siguientes:

  1. Encapsulación y ocultación de detalles de implementación : al utilizar@propertydecoradores, puede encapsular el acceso a propiedades dentro de los métodos, ocultando así los detalles de implementación. Esto ayuda a evitar que los usuarios accedan directamente y modifiquen el estado interno de la clase, mejorando la encapsulación de la clase.

  2. Coherencia del acceso a la propiedad : después de convertir un método en una propiedad, puede utilizar el operador de punto (.) para acceder a la propiedad , de forma coherente con la sintaxis al acceder a la propiedad directamente. Esto mejora la legibilidad y la coherencia del código.

  3. Calcular valores de propiedadPuede @propertyagregar lógica en el método para calcular el valor de la propiedad . Esto le permite generar propiedades dinámicamente según sea necesario sin tener que almacenar datos adicionales.

  4. Validación y protección de propiedades : @propertylos métodos le permiten validar y proteger los valores de propiedades antes de configurarlos . Puede @propertyagregar lógica de validación en el método de establecimiento para garantizar que el valor de la propiedad cumpla ciertas condiciones.

  5. Bueno para refactorizar : si decide cambiar la forma en que se implementa una propiedad, puede refactorizar un método sin cambiar el código de usuario de la clase@property. Esto ayuda a mantener la compatibilidad del código.

class Person:
    def __init__(self, gender):
        self.__gender = gender    # 私有的

    @property   # 装饰器
    def gender(self):
        return self.__gender

    @gender.setter
    def gender(self, value):
        if value != 'boy' and value != 'girl':
            raise ValueError('Gender must be boy or girl')
        else:
            self.__gender = value

if __name__ == '__main__':
    p = Person('boy')
    print(p.gender)     # boy
    p.gender = 'girl'   # @gender.setter
    print(p.gender)     # girl
    p.gender = 'other'  # @gender.setter
    print(p.gender)     # ValueError: Gender must be boy or girl

Dos decoradores personalizados

def logger(func):  # 被装饰的函数作为方法的参数
    def class_time():
        print('二、四、六晚上上课')
        print('_' * 30)
        func()
        print('_' * 30)
        print('大概下课时间,22:30')
    return class_time

# 函数式
@logger
def work():
    print('老师在上课')

@logger
def work2():
    print('学生不想上课')

if __name__ == '__main__':
    work()
    print('\n')
    work2()

Tres parámetros de decorador y parámetros de función.

*args, **kwargs    # Parámetros posicionales personalizados y parámetros de palabras clave

from functools import wraps

def main_logger(time_key='二、四、六晚上八点', end_time='21:30'):
    def logger(func):
        @wraps(func)
        def class_time(*args, **kwargs):
            print('上课时间:', time_key)
            func(*args, **kwargs)
            print('下课时间:', end_time)
        return class_time
    return logger

# 核心功能
@main_logger()
def work():
    print('三月要上课啦!')

@main_logger(time_key='一、三、五晚上')
def work2():
    print('老子今天不上课')

@main_logger()
def work4(name, subject):
    print(f'{name}在上课 {subject}课程')

if __name__ == '__main__':
    # work()
    # work2()
    work4('march', 'dj')

4. Utiliza objetos como decoradores.

class Logs:
    def __init__(self, start_time='二、四、六晚上20:00', end_time='21:30'):
        self.start_time = start_time
        self.end_time = end_time

    # 重写object类中 call 方法
    def __call__(self, func):    # func是被装饰的函数
        def class_time(*args, **kwargs):
            print('上课时间:', self.start_time)
            func(*args, **kwargs)
            print('下课时间:', self.end_time)
        return class_time

@Logs()   # 类对象装饰
def work(name, subject):
    print(f'{name}在上 {subject}')

if __name__ == '__main__':
    work('your', '奇奇怪怪的课')

Cinco funciones parciales

functools.partial : debe pasar la función original y los parámetros que deben pasarse

Los dos métodos siguientes son equivalentes:

import functools
int3 = functools.partial(int, base=16)
print(int3('abd'))

Solo escribe:

def int2(num, base=16):
    return int(num, base)

print(int2('abd'))

Seis modifican dinámicamente el estado de la clase.

@staticmethody son decoradores utilizados para definir métodos estáticos y métodos de clase en Python. Tienen diferentes funciones y usos. @classmethod

@staticmethod:

  • Los métodos estáticos son métodos definidos en una clase que no dependen de las instancias de la clase ni del estado de la clase.
  • Generalmente se usa en situaciones donde no se requiere acceso a propiedades o métodos de instancia y puede considerarse como una función de utilidad de la clase.
  • El primer parámetro de un método estático generalmente no es selfo cls, sino un parámetro ordinario que se utiliza para pasar los datos requeridos por el método.

@classmethod:

  • Un método de clase es un método definido en una clase, pero no tiene nada que ver con las instancias de la clase, sino que depende de la clase misma.
  • El primer parámetro de un método de clase generalmente se clsusa para representar la clase misma, que puede acceder a las propiedades de la clase y llamar a otros métodos de clase.
  • Los métodos de clase generalmente se usan como métodos de fábrica o para realizar algunas operaciones en la clase antes de crear una instancia.

6.1 Definir clases

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

if __name__ == '__main__':
    p = Person('march', 20)
    print('name:', p.name)
    print('age:', p.age)

6.2 Agregar atributos

p.gender = 'boy'  # 动态添加属性
print('gender:', p.gender)

6.3 Método de suma dinámica

def fun():
    print('我是一个普通函数,即将成为一个实例 方法')

# 动态添加方法
p.show = fun
p.show()

def fun2(self):
    print('我也是一个普通函数,第一个参数是self,类成员方法的第一个参数就是self')

# 第二种添加方式
p.show2 = types.MethodType(fun2, p)
p.show2()

6.4 Agregar dinámicamente métodos estáticos

@staticmethod
def static_func():
    print('马上成为Person类中的静态方法, staticmethod')

# 动态添加静态方法, 通过类名调用
Person.sf = static_func
Person.sf()

6.5 Agregar dinámicamente métodos de clase

@classmethod
def class_func(cls):
    print('马上成为Person类中的类方法, class_method')

# 动态添加类方法
Person.cf = class_func
    Person.cf()

# 动态添加类方法
print(dir(Person))
print(dir(p))

6.6 Agregar atributos de restricción

__slots__ : Ahora la adición de atributos.

class Person:
    __slots__ = ('name', 'age')
    def __init__(self, name, age):
        self.name = name
        self.age = age

if __name__ == '__main__':
    p = Person('march', 20)

    p.gender = 'boy'  # __slots__ = ('name', 'age')  限制可以添加的属性
    print('gender:', p.gender)

Supongo que te gusta

Origin blog.csdn.net/March_A/article/details/133431242
Recomendado
Clasificación