10. python高级主题

2024-05-18

高级主题

装饰器

  • 装饰器是一种用于修改或增强函数行为的高级技术。它本质上是一个函数,接受一个函数作为参数,并返回一个新的函数。
# 定义装饰器
def my_decorator(func):
    def wrapper():
        print("在函数执行之前")
        func()
        print("在函数执行之后")
    return wrapper

# 使用装饰器
@my_decorator
def say_hello():
    print("Hello!")

say_hello()
  • 在这个示例中,my_decorator 装饰器在 say_hello 函数的执行前后添加了额外的打印语句。

  • 装饰器可以接受参数,以提供更灵活的功能。

# 定义带参数的装饰器
def repeat(num_times):
    def decorator_repeat(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                func(*args, **kwargs)
        return wrapper
    return decorator_repeat

@repeat(num_times=3)
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")
  • 在这个示例中,repeat 装饰器接受参数 num_times,并重复执行 say_hello 函数指定的次数。

生成器

  • 生成器是一种特殊的迭代器,使用 yield 关键字生成值。与普通函数不同,生成器在每次生成值后暂停,并在下次调用时继续执行。
# 定义生成器
def count_up_to(max):
    count = 1
    while count <= max:
        yield count
        count += 1

# 使用生成器
counter = count_up_to(5)
for num in counter:
    print(num)
  • 在这个示例中,count_up_to 生成器每次生成一个数值,并在达到 max 值时停止。

高阶生成器

  • 生成器可以与其他生成器组合使用,以创建复杂的数据处理管道。
def generator1():
    yield from range(3)

def generator2():
    yield from range(3, 6)

# 组合生成器
def combined_generator():
    yield from generator1()
    yield from generator2()

for value in combined_generator():
    print(value)

Lambda函数

  • Lambda函数是一种简洁的匿名函数,用于定义简单的函数。常用于需要一个短期函数的场景。
# 示例代码
add = lambda x, y: x + y
print(add(3, 5))  # 输出 8

列表推导式

  • 列表推导式是一种创建列表的简洁方法,可以在一行代码中生成列表。
# 示例代码
squares = [x**2 for x in range(10)]
print(squares)  # 输出 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

面向对象编程的高级特性

  • 包括类方法静态方法属性装饰器等。
# 示例代码
class MyClass:
    class_variable = "I am a class variable"
  
    def __init__(self, instance_variable):
        self.instance_variable = instance_variable
  
    @classmethod # 类方法
    def class_method(cls):
        return cls.class_variable
  
    @staticmethod # 静态方法
    def static_method():
        return "I am a static method"
  
    @property # 属性装饰器
    def instance_property(self):
        return self.instance_variable

obj = MyClass("I am an instance variable")
print(MyClass.class_method())      # 输出 "I am a class variable"
print(MyClass.static_method())     # 输出 "I am a static method"
print(obj.instance_property)       # 输出 "I am an instance variable"

1. 类方法(Class Method)

类方法使用 @classmethod 装饰器定义,第一个参数是类本身,通常命名为 cls。类方法可以访问类变量和修改类状态。

class MyClass:
    class_variable = "I am a class variable"

    def __init__(self, instance_variable):
        self.instance_variable = instance_variable

    @classmethod
    def class_method(cls):
        return cls.class_variable

# 使用类方法
print(MyClass.class_method())  # 输出 "I am a class variable"

在这个示例中,class_method 是一个类方法,它返回类变量 class_variable 的值。

2. 静态方法(Static Method)

静态方法使用 @staticmethod 装饰器定义,不需要传入类或实例作为参数。静态方法通常用于执行一些逻辑操作,这些操作与类和实例无关。

class MyClass:

    @staticmethod
    def static_method():
        return "I am a static method"

# 使用静态方法
print(MyClass.static_method())  # 输出 "I am a static method"

在这个示例中,static_method 是一个静态方法,它不访问类或实例的数据,仅执行独立的逻辑。

3. 属性装饰器(Property Decorator)

属性装饰器 @property 允许你将类的方法转换为只读属性,使得你可以像访问属性一样访问方法。这使得类的设计更直观和易于使用。

1. 基本用法

使用 @property 可以定义一个只读属性。

class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property  # 将方法转换为属性
    def radius(self):
        return self._radius

# 创建对象并访问属性
c = Circle(5)
print(c.radius)  # 输出 5

在这个示例中,radius 方法被转换为一个只读属性,因此你可以像访问属性一样访问它,而不需要调用方法。

2. 设置器(Setter)

除了只读属性,属性装饰器还可以定义属性的设置器,允许你在设置属性值时执行一些额外的逻辑。使用 @<property_name>.setter 装饰器来定义设置器。

class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):
        return self._radius

    @radius.setter  # 定义设置器
    def radius(self, value):
        if value < 0:
            raise ValueError("半径不能为负数")
        self._radius = value

# 创建对象并设置属性
c = Circle(5)
print(c.radius)  # 输出 5
c.radius = 10
print(c.radius)  # 输出 10
# c.radius = -1  # 会引发 ValueError: 半径不能为负数

在这个示例中,radius 属性有一个设置器,当尝试设置负值时会引发异常。

3. 删除器(Deleter)

同样地,你还可以定义属性的删除器,使用 @<property_name>.deleter 装饰器来定义删除器。

class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        if value < 0:
            raise ValueError("半径不能为负数")
        self._radius = value

    @radius.deleter  # 定义删除器
    def radius(self):
        print("删除半径属性")
        del self._radius

# 创建对象并删除属性
c = Circle(5)
print(c.radius)  # 输出 5
del c.radius
# print(c.radius)  # 会引发 AttributeError: 'Circle' object has no attribute '_radius'

在这个示例中,radius 属性有一个删除器,当属性被删除时会执行特定的逻辑。

4. 完整示例

一个包含所有三种方法的完整示例如下:

class Circle:
    def __init__(self, radius):
        self._radius = radius

    @property
    def radius(self):
        return self._radius

    @radius.setter
    def radius(self, value):
        if value < 0:
            raise ValueError("半径不能为负数")
        self._radius = value

    @radius.deleter
    def radius(self):
        print("删除半径属性")
        del self._radius

# 使用属性装饰器
c = Circle(5)
print(c.radius)  # 输出 5
c.radius = 10
print(c.radius)  # 输出 10
del c.radius

通过使用属性装饰器,你可以使类的接口更加直观和易于使用,同时能够控制属性的访问和修改。