摘要

补充python的一些进阶知识,python高级特性

  • 面向对象
  • 闭包和装饰器
  • 网络和多线程
  • 生成器和正则表达
  • 算法

面向对象

封装

与其他语言的区别在于写法,思想是一致的,比如私有属性只要__property_name就可以实现封装,外部不能直接访问。如果要修改的话则需要封装一个方法来作为修改和提取。 @property注解可以用来将一个方法转换为属性,外部可以直接访问,但是不能直接赋值。@property_name.setter注解可以用来将一个方法转换为属性的赋值方法,外部可以直接赋值。 __init__会在初始化的时候执行,

class OopClass:
    def __init__(self):
        print("OopClass init")
        # 公共属性
        self.name = "OopClass"
        # 私有属性
        self.__age = 18
        # 公共属性
        self.is_male = True

    # 属性的getter和setter方法
    @property
    def is_male(self):
        return self.is_male
    @is_male.setter
    def is_male(self, value):
        if isinstance(value, bool):
            print("is_male is valid")
            self.is_male = value
        else:
            raise ValueError("is_male is not valid")

    def get_name(self):
        return self.name

    def get_age(self):
        return self.__age

    def set_age(self, age):
        # 判断age是否为int类型且大于0
        if isinstance(age, int) and age > 0:
            print("age is valid")
            self.__age = age
        else:
            raise ValueError("age is not valid")

抽象类封装,子类必须实现抽象方法,如下面的abstract_method1和abstract_method2。 抽象类的特产是必须继承ABC类,并且必须使用@abstractmethod注解来定义抽象方法。

from abc import ABC, abstractmethod
# 抽象类
class AbstractClass(ABC):
    # 属性
    name = "AbstractClass1"
    def __init__(self):
        print("AbstractClass init")

    @abstractmethod
    def abstract_method1(self):
        pass

    @abstractmethod
    def abstract_method2(self):
        pass

继承

python里面的继承比较有意思,他可以多继承,连续继承。相同的属性和方法前面会覆盖后面的。

class Grandpa:
    """祖父类"""
    def __init__(self, name):
        self.name = name

    def walk(self):
        print("grandpa:I'm walking.")

class Father:
    """父亲类"""
    def __init__(self, name):
        self.name = name

    def walk(self):
        print("father:I'm walking.")

    def say(self):
        print("father:I'm saying.")

class Mother:
    """母亲类"""
    def __init__(self, name):
        self.name = name

    def say(self):
        print("mother:I'm saying.")


class Child(Grandpa,Mother, Father):
    """子类"""
    def dance(self):
        print("child:I'm dancing.")

child = Child("小王")
print(child.name)
child.walk()
child.say()
child.dance()
# 小王
# grandpa:I'm walking.
# mother:I'm saying.
# child:I'm dancing.

多态

Python 不支持传统意义上的函数重载来实现多态,Python 的多态主要通过 继承+方法重写 来实现 如下:

class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

# 多态的体现
def make_animal_speak(animal: Animal):
    print(animal.speak())

dog = Dog()
cat = Cat()

make_animal_speak(dog)  # 输出: Woof!
make_animal_speak(cat)  # 输出: Meow!

装饰器

python里面的装饰器从python2.4开始支持,本质是函数替换,接收参数是当前修饰的函数,返回一个新的函数,也就是对当前修饰的函数的改造。 自定义装饰器一般使用闭包实现

staticmethod

类的普通对象,第一个参数是self
@staticmethod修饰的函数,无需实例化类对象即可直接调用方法,参数没有self和cls如下:

class MyClass:
    @staticmethod
    def my_static_method(a, b):
        print("这是一个静态方法,参数为:", a, b)

# 无需实例化类对象即可直接调用方法
MyClass.my_static_method(1, 2)  # 输出: 这是一个静态方法,参数为: 1 2

classmethod

第一个参数是cls,代表的是当前的类对象

class MyClass:
    # 类属性
    class_name = "MyClass"
    @classmethod
    def my_class_method(cls, a, b):
        print("这是一个类方法,参数为:", cls, a, b)
        # 可以通过cls来调用类的其他方法和属性
        cls.my_static_method(a, b)
        # 可以通过cls来调用类的其他属性
        print(cls.class_name)

常用用途:

  • 工厂方法
  • 操作类变量
  • 实现可继承的多态行为
  • 替代构造函数
  • 当你不确定未来是否会被继承

自定义装饰器

自定义装饰器一般使用闭包的方式实现,如下:

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Something is happening before the function is called.")
        func(*args, **kwargs)
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")