Python 使用到的一丢丢代码片段

  • Python 装饰器终极写法
 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
# 假如需要用到装饰的功能(建议经常使用),那么建议使用下面写法
# 目的是既可以使用不带参数的装饰,有可以使用带参数的作用
# wraps的目的是为了保留原有函数的文档信息,使用wraps后,可以使用__wrapped__访问原始的函数(不经常)
# 注意:
# 非实例的装饰器,在导入文件时就会调用,如果用于装饰类实例的函数,需注意,这时的self参数是没有的,需要设置进去
# 类实例的装饰器在生成实例时,调用。
from functools import wraps, partial
import logging

def logged(func=None, *, level=logging.DEBUG, name=None, message=None):
    if func is None:
        return partial(logged, level=level, name=name, message=message)
  # 一些其他操作
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 一些其他操作,可以添加其他功能,等等
        return func(*args, **kwargs)

    return wrapper

# Example use
@logged
def add(x, y):
    return x + y

@logged(level=logging.CRITICAL, name='example')
def spam():
    print('Spam!')

  • Python 自定义生成类
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 普通人想到的运行字符串的代码是exeC, 更优雅的方式是使用types.new_class()
# stock.py
# Example of making a class manually from parts

# Methods
def __init__(self, name, shares, price):
    self.name = name
    self.shares = shares
    self.price = price
def cost(self):
    return self.shares * self.price

cls_dict = {
    '__init__' : __init__,
    'cost' : cost,
}

# Make a class
import types

Stock = types.new_class('Stock', (), {}, lambda ns: ns.update(cls_dict))
Stock.__module__ = __name__
  • Python 使用元类控制实例的创建
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 比如单例模式
# 关键是传入metacalss=XXX
# 可扩展为缓存之类
class Singleton(type):
    def __init__(self, *args, **kwargs):
        self.__instance = None
        super().__init__(*args, **kwargs)

    def __call__(self, *args, **kwargs):
        if self.__instance is None:
            self.__instance = super().__call__(*args, **kwargs)
            return self.__instance
        else:
            return self.__instance

# Example
class Spam(metaclass=Singleton):
    def __init__(self):