首页 > 解决方案 > 同一个类中的同名函数 - 有没有一种优雅的方法来确定调用哪个?

问题描述

出于特定原因,我正在尝试在 Python 脚本中进行产品版本控制,但我无法弄清楚如何以优雅的方式进行。

目前,我正在做类似下面的事情。但是,当版本内容发生变化时,脚本很难维护。

class Product(object):

    def __init__(client):
        self.version = client.version  # Get client version from another module

    def function():
        if self.version == '1.0':
            print('for version 1.0')
        elif self.version == '2.0':
            print('for version 2.0')
        else:
            print(f'function not support {self.version}')

因此,我想做类似下面的事情来分隔具有相同名称的函数。

class Product(object):

    def __init__(client):
        self.version = client.version  # Get client version from another module

    def function():
        print('for version 1.0')

    def function():
        print('for version 2.0')

我正在考虑使用装饰器来实现这一点:

class Product(object):

    def __init__(client):
        self.version = client.version  # Get client version from another module

    @version(1.0)
    def function():
        print('for version 1.0')

    @version(2.0)
    def function():
        print('for version 2.0')

但是,我无法弄清楚如何......装饰者似乎无法进行这种操作,或者我只是不明白如何去做。

有没有一种优雅的方法来做到这一点?

标签: pythonversion-controlpython-3.6python-decorators

解决方案


继承可能是做到这一点的最佳方式,但由于您专门询问了装饰器,我想展示您可以使用装饰器来做到这一点。

您需要使用字典按版本存储函数,然后在运行时查找要使用的版本。这是一个例子。

version_store = {}

def version(v):
    def dec(f):
        name = f.__qualname__
        version_store[(name, v)] = f
        def method(self, *args, **kwargs):
            f = version_store[(name, self.version)]
            return f(self, *args, **kwargs)
        return method
    return dec

class Product(object):
    def __init__(self, version):
        self.version = version

    @version("1.0")
    def function(self):
        print("1.0")

    @version("2.0")
    def function(self):
        print("2.0")

Product("1.0").function()
Product("2.0").function()

推荐阅读