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

时间:2015-10-07 18:48:46

标签: python class instance-methods

有没有办法将除指定的几个以外的所有实例调用传递给实例的属性?我试图找出为PyMongo编写包装类的最简单方法,如下所示:

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()

1 个答案:

答案 0 :(得分:2)

您可以通过在班级上定义__getattr__来简单地拦截属性访问。只要您访问该实例中实际不存在的属性,就会调用此方法;所以你可以将它们传递给self.collection

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

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