python Python函数装饰器,允许您重载具有相同名称的函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python Python函数装饰器,允许您重载具有相同名称的函数相关的知识,希望对你有一定的参考价值。

# -*- coding: utf-8 -*-
# @Author: cody kochmann
# @Date:   2017-12-16 10:14:56
# @Last Modified time: 2017-12-16 12:15:02

from functools import wraps

def overload(fn):
    '''
This function decorator allows you to overload already defined functions. The
execution of overloaded functions is done by trying the newest version first
and if it fails, that function's predecessor will be ran.

While this does seem like a sloppy way to go about choosing the execution of
functions, this gives you far more control in terms of how you want each
function to be selected.

This approach rewards funtions that are designed with proper input validation,
which you should be adding anyways.

#------------------------------------------------------------------------------
#   Example Usage Below
#------------------------------------------------------------------------------

def my_print(arg):
    print('running original my_print')
    print(arg)

@overload
def my_print(arg):
    assert type(arg) == list
    print('running list my_print')
    print(', '.join(str(i) for i in arg))

@overload
def my_print(arg):
    assert type(arg) == dict
    print('running dict my_print')
    out = ('='.join((str(k), str(v))) for k,v in arg.items())
    print(' | '.join(out))

my_print(list(range(10)))
# running list my_print
# 0, 1, 2, 3, 4, 5, 6, 7, 8, 9

my_print(tuple(range(10)))
# running original my_print
# (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

my_print({i:i*2 for i in range(10)})
# running dict my_print
# 0=0 | 1=2 | 2=4 | 3=6 | 4=8 | 5=10 | 6=12 | 7=14 | 8=16 | 9=18

'''
    @wraps(fn)
    def wrapper(*args, **kwargs):
        try:
            return fn(*args, **kwargs)
        except:
            return wrapper.function_to_overload(*args, **kwargs)
    
    # attach the old version to wrapper so wrapper can reference it
    wrapper.function_to_overload = fn.__globals__[fn.__name__]
    
    # this returns true if the input has an empty docstring
    has_empty_doc = lambda fn:getattr(fn, '__doc__', None) in {None, ''}
    
    # inherit the original overloaded function's documentation if fn doesn't have one
    if has_empty_doc(wrapper) and not has_empty_doc(wrapper.function_to_overload):
        # None is the python standard value for no doc string
        wrapper.__doc__ = getattr(wrapper.function_to_overload, '__doc__', None)
    
    # do some cleanup
    del has_empty_doc
    
    # return the output
    return wrapper

以上是关于python Python函数装饰器,允许您重载具有相同名称的函数的主要内容,如果未能解决你的问题,请参考以下文章

Python 没有函数重载?如何用装饰器实现函数重载?

为什么 Python 没有函数重载?如何用装饰器实现函数重载?

为什么 Python 没有函数重载?如何用装饰器实现函数重载?

为什么 Python 没有函数重载?如何用装饰器实现函数重载?

为什么 Python 没有函数重载?如何用装饰器实现函数重载?

为什么 Python 没有函数重载?如何用装饰器实现函数重载?