Python Notes 05 (Verwendung von Dekoratoren)

Der Einsatz eines Dekorateurs (@property)

@propertyIst ein Dekorator, der zum Erstellen von Eigenschaften in Python verwendet wird. Seine Funktion besteht darin, eine Klassenmethode in eine Klasseneigenschaft umzuwandeln, sodass auf  die Methode wie auf eine Eigenschaft zugegriffen werden kann, ohne die Syntax eines Funktionsaufrufs zu verwenden. Die Hauptvorteile der Verwendung @propertysind folgende:

  1. Kapselung und Ausblenden von Implementierungsdetails : Mithilfe von@propertyDekoratoren können Sie den Zugriff auf Eigenschaften innerhalb von Methoden kapseln und so Implementierungsdetails verbergen. Dadurch wird verhindert, dass Benutzer direkt auf den internen Status der Klasse zugreifen und diesen ändern, wodurch die Kapselung der Klasse verbessert wird.

  2. Konsistenz des Eigenschaftszugriffs : Nach der Konvertierung einer Methode in eine Eigenschaft können Sie mit dem Punktoperator (.) auf die Eigenschaft zugreifen , wobei die Syntax beim direkten Zugriff auf die Eigenschaft konsistent ist. Dies verbessert die Lesbarkeit und Konsistenz des Codes.

  3. Eigenschaftswerte berechnen : Sie  können @propertyder Methode Logik hinzufügen, um den Wert der Eigenschaft zu berechnen . Dadurch können Sie Eigenschaften nach Bedarf dynamisch generieren, ohne zusätzliche Daten speichern zu müssen.

  4. Eigenschaftsvalidierung und -schutz : @propertyMit Methoden können Sie Eigenschaftswerte validieren und schützen, bevor Sie sie festlegen . Sie können @propertyder Setter-Methode eine Validierungslogik hinzufügen, um sicherzustellen, dass der Eigenschaftswert bestimmte Bedingungen erfüllt.

  5. Gut für die Umgestaltung : Wenn Sie die Art und Weise ändern möchten, wie eine Eigenschaft implementiert wird, können Sie eine Methode umgestalten, ohne den Benutzercode der Klasse zu ändern@property. Dies trägt dazu bei, die Codekompatibilität aufrechtzuerhalten.

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

Zwei maßgeschneiderte Dekorateure

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()

Drei Dekorationsparameter und Funktionsparameter

*args, **kwargs    # Benutzerdefinierte Positionsparameter und Schlüsselwortparameter

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. Verwenden Sie Objekte als Dekoration

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', '奇奇怪怪的课')

Fünf Teilfunktionen

functools.partial : Sie müssen die ursprüngliche Funktion und die zu übergebenden Parameter übergeben

Die folgenden zwei Methoden sind äquivalent:

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

Einfach schreiben:

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

print(int2('abd'))

Sechs ändern den Klassenstatus dynamisch

@staticmethodund sind Dekoratoren , die zum Definieren statischer Methoden und Klassenmethoden in Python verwendet werden. Sie haben unterschiedliche Funktionen und Verwendungszwecke. @classmethod

@staticmethod::

  • Statische Methoden sind in einer Klasse definierte Methoden, die nicht von Instanzen der Klasse oder dem Status der Klasse abhängen.
  • Sie wird normalerweise in Situationen verwendet, in denen kein Zugriff auf Instanzeigenschaften oder -methoden erforderlich ist, und kann als Dienstprogrammfunktion der Klasse betrachtet werden.
  • Der erste Parameter einer statischen Methode ist normalerweise nicht selfor cls, sondern ein gewöhnlicher Parameter, der zur Übergabe der von der Methode benötigten Daten verwendet wird.

@classmethod::

  • Eine Klassenmethode ist eine in einer Klasse definierte Methode, die jedoch nichts mit Instanzen der Klasse zu tun hat, sondern von der Klasse selbst abhängt.
  • Der erste Parameter einer Klassenmethode wird normalerweise clsverwendet, um die Klasse selbst darzustellen, die auf die Eigenschaften der Klasse zugreifen und andere Klassenmethoden aufrufen kann.
  • Klassenmethoden werden normalerweise als Factory-Methoden verwendet oder um einige Operationen an der Klasse auszuführen, bevor eine Instanz erstellt wird.

6.1 Klassen definieren

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 Attribute hinzufügen

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

6.3 Dynamische Additionsmethode

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

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

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

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

6.4 Statische Methoden dynamisch hinzufügen

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

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

6.5 Klassenmethoden dynamisch hinzufügen

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

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

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

6.6 Einschränkungsattribute hinzufügen

__slots__ : Jetzt das Hinzufügen von Attributen

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)

Guess you like

Origin blog.csdn.net/March_A/article/details/133431242