本文主要介绍Python中,通过装饰器实现控制不同平台的函数定义,类似C语言的中宏定义。

实现效果:

@linux
def my_callback(*args, **kwargs):
    print("Linux 平台函数实现 @ Linux")
    return

@windows
def my_callback(*args, **kwargs):
    print("Windows平台函数实现 @ Windows")

通过装饰器控制函数定义:

1) 不支持一个函数多个装饰器

import sys
import platform

def _ifdef_decorator_impl(plat, func, frame):
    if platform.system() == plat:
        return func
    elif func.__name__ in frame.f_locals:
        return frame.f_locals[func.__name__]
    else:
        def _not_implemented(*args, **kwargs):
            raise NotImplementedError(
                f"Function {func.__name__} is not defined "
                f"for platform {platform.system()}.")

        return _not_implemented


def windows(func):
    return _ifdef_decorator_impl('Windows', func, sys._getframe().f_back)


def macos(func):
    return _ifdef_decorator_impl('Darwin', func, sys._getframe().f_back)
    
def linux(func):
    return _ifdef_decorator_impl('Linux', func, sys._getframe().f_back)

@linux
def my_callback(*args, **kwargs):
    print("Linux 平台函数实现 @ Linux")

@windows
def my_callback(*args, **kwargs):
    print("Windows平台函数实现 @ Windows")
#执行函数
my_callback()

2)支持一个函数多个装饰器

import sys
import platform

class IfDefDecoratorPlaceholder:
    def __init__(self, func):
        self.__name__ = func.__name__
        self._func = func

    def __call__(self, *args, **kwargs):
        raise NotImplementedError(
            f"Function {self._func.__name__} is not defined for "
            f"platform {platform.system()}.")


def _ifdef_decorator_impl(plat, func, frame):
    if platform.system() == plat:
        if type(func) == IfDefDecoratorPlaceholder:
            func = func._func
        frame.f_locals[func.__name__] = func
        return func
    elif func.__name__ in frame.f_locals:
        return frame.f_locals[func.__name__]
    elif type(func) == IfDefDecoratorPlaceholder:
        return func
    else:
        return IfDefDecoratorPlaceholder(func)


def linux(func):
    return _ifdef_decorator_impl('Linux', func, sys._getframe().f_back)


def windows(func):
    return _ifdef_decorator_impl('Windows', func, sys._getframe().f_back)


def macos(func):
    return _ifdef_decorator_impl('Darwin', func, sys._getframe().f_back)


@macos
@linux
def my_callback(*args, **kwargs):
    print("Linux 和 MacOS平台函数实现 ")
    return


@windows
def my_callback(*args, **kwargs):
    print("Windows平台函数实现 ")
#执行函数
my_callback()

推荐文档