首页 > 解决方案 > 为 python 类实现通用和动态外观

问题描述

我想在 python 中实现一种外观模式。但是,因为我需要对所有方法都做同样的事情,所以我想以一种通用的方式来做。让我举个例子:

class MyObject:

    def __init__(self, *args, **kwargs):
        # do something with args/kwargs

    def method1(self, x):
        # do something

    def method2(self, x, a):
        # do something

    def method3(self, x, a, b):
        # do something


class MyFacade:

    def __init__(self, *args, **kwargs):
        self.x = SOMETHING
        self.obj = MyObject(*args, **kwargs)

    def method1(self):
        return self.obj.method1(self.x)

    def method2(self, a):
        return self.obj.method2(self.x, a)

    def method3(self, a, b):
        return self.obj.method3(self.x, a, b)

现在因为我有几个像 MyObject 这样的类,我想要一种通用的方法来为它们中的每一个创建一个 MyFacade,而不必为每个方法编写代码(它们都或多或少地相同)。此外,如果 MyObject 发生更改,我希望 MyFacade 不会受到影响,而是透明地处理 MyObject 中的任何接口更改。

谢谢您的帮助!


编辑:

这可行,但是从 MyInterface 继承的方法由于额外的参数而引发 TypeError 。

class MyObject:

    def method1(self, x):
        print(x)

    def method2(self, x, a):
        print(x, a)

    def method3(self, x, a, b):
        print(x, a, b)


class MyInterface:

    def methodX(self):
        print("YAY!")



class MyFacade(MyInterface, MyObject):

    def __init__(self):
        self.x= "WHATEVER"

    def __getattribute__(self, item):
        result = super().__getattribute__(item)
        if callable(result):
            return lambda *args, **kwargs: result(self.x, *args, **kwargs)
        return result

编辑:

我以这种方式修改了条件,现在 MyInterface 的问题消失了:

if callable(result) and result.__name__ in MyObject.__dict__:

标签: pythonpython-3.xfacade

解决方案


这样做的明显方法是利用类和函数名称是变量并且可以分配的事实,因此 MyFacade 可以定义如下:

class MyFacade:

    def __init__(self,obj, *args, **kwargs):
        self.x = SOMETHING
        self.obj = obj(*args, **kwargs)

    def method1():
        return self.obj.method1(self.x)

    def method2(a):
        return self.obj.method2(self.x, a)

    def method3(a, b):
       return self.obj.method1(self.x, a, b)

设置电话将是例如:

fasc = MyFscade(MyOject,*args,**kwargs)

推荐阅读