如何将实例方法调用传递给实例 属性?

How to pass instance method calls on to instance property?

有没有办法将除了指定的少数实例调用之外的所有实例调用传递给实例的 属性?我正在尝试找出为 PyMongo 编写包装器 class 的最简单方法,如下所示:

class Mongo():   
    def __init__(self, db_name, collection_name):
        self.client = MongoClient()
        self.collection = self.client[db_name][collection_name]

要是能说pass all self.function calls to self.collection unless you are calling something in this list: [__init__, __dict__, etc...]就好了。是否有允许我执行此操作的语言功能?我唯一能想到的是用 __call__ 做一些事情,其中​​函数名称将是传递给 __call__ 的值,但就处理不同数量和类型的参数而言,它似乎会变得冒险.我正在设想类似的东西:

def __call__(self, value, *args, **kargs):
    func = getattr(self.test, value)
    func(self.test, *args, **kargs)

我还没有完成上述工作。特别是,我传递了太多的论点。通过 args, kargs*args, **kargs 并没有按照我希望的方式自行解决。 我需要做什么才能将用户指定的任何参数传递给用户指定的任何函数?(粘贴在问题末尾的完整最小工作示例)

但是,即使我可以使上述工作正常进行,符号也很笨拙。我真的很想能够做更多类似的事情:

f.f1(4,5)

而不是

f("f1", 4, 5) 

是否有更好的替代方案来替代上述 __call__ 场景,即使我可以按需要运行它?

这是无效的代码:

class test1():
    def __init__(self, test):
        self.test = test

    def __call__(self, value, *args, **kargs):
        func = getattr(self.test, value)
        func(args, kargs)

class test2():
    def f1(a, b):
        print(a+b)

    def f2(stringy):
        print(stringy)

    def f3(a = 7, b = 14):
        print("a is %d and b is %b"%(a,b))


def main():
    t2 = test2()
    t1 = test1(t2)
    t1("f1",4, 5) #gives an error that I am passing 3 args instead of the 2 specified by func definition

if __name__ == "__main__":
    main()

您可以通过在 class 上定义 __getattr__ 来相当简单地拦截属性访问。每当您访问该实例中实际不存在的属性时,都会调用此方法;这样您就可以将它们传递给 self.collection.

甚至不需要区分方法和其他属性;访问在调用之前完成,因此返回集合的方法将允许 Python 做正确的事情。

def __getattr__(self, attr):
    return getattr(self.collection, attr)