python2.7:在实例方法中传递kwargs

时间:2014-08-01 19:43:15

标签: python python-2.7 inheritance locals

如果我想从一个函数向另一个函数传递一个args的缩进列表,我可以使用locals函数。然而,如果我在一个实例方法中,这会失败,因为self不能作为kwarg传递。我可以创建一个本地词典,然后删除自己。我想知道是否有更优雅的方式来做这件事 - 对我来说似乎有很多。

class MyObj:
    def test(self, a=1, b=2, c=3, d=4):
        return [a,b,c,d]

class MyVerboseObj(MyObj):
    def test(self, a=1, b=2, c=3, d=4):
        print "RUNNING TEST a=%d"%a
        kwargs = locals()
        del kwargs["self"]
        return MyObj.test(self, **kwargs)

MyVerboseObj().test()

有没有更好的方法将相同的列表args从MyVerboseObj.test传递给MyObj.test?

**更新**

这是一个简化的例子来说明我的问题。一个更实际的例子可能是:

class GenericShow:
    def __init__(self, path):
        self.path = path
    def getRenderPath(self, extn="jpg", colspace="rgb"):
        return "%s/render_%s.%s"%(self.path, colspace, extn)
    def hasGenericShowHandler(self):
        try:
            import GenericShowHandler
            return True
        except: pass

class UkShow(GenericShow):
     def getRenderPath(self, extn="jpg", colspace="rgb"):
         if self.hasGenericShowHandler():
             kwargs = locals()
             kwargs.pop("self")
             return GenericShow.getRenderPath(self, **kwargs)
         else:
            return "%s/blah/render_%s.%s"%(path, colspace, extn)

show = UkShow("/jobs/test")
show.hasGenericShowHandler()
print show.getRenderPath()

我有很多展示对象,不同的模块由不同的模块和不同的命名约定定义 - 我试图创建具有共同功能的展示对象。

2 个答案:

答案 0 :(得分:2)

如果您不想覆盖父级的功能(因为您想使用它) - 只需避免通过给它一个不同的名称来覆盖它!

class MyObj:
    def base_test(self, a=1, b=2, c=3, d=4):
        return [a,b,c,d]

class MyVerboseObj(MyObj):
    def test(self, a=1, b=2, c=3, d=4):
        print "RUNNING TEST a=%d"%a
        kwargs = locals()
        del kwargs["self"]
        return self.base_test(**kwargs)

print MyVerboseObj().test()

答案 1 :(得分:0)

使用locals()很少是一个好主意。这种方法对代码的修改是混乱和脆弱的,因为添加任何局部变量会使你的调用陷入困境。

我会更明确地说:

class MyObj:
    def test(self, a=1, b=2, c=3, d=4):
        return [a,b,c,d]

class MyVerboseObj(MyObj):
    def test(self, a=1, b=2, c=3, d=4):
        print "RUNNING TEST a=%d"%a
        return MyObj.test(self, a, b, c, d)

MyVerboseObj().test()

我知道这很乏味,但它避免了一些麻烦。此外,它更有效。

或者,如果你没有丢失签名,你可以接受*args, **kwargs作为覆盖函数的参数:

class MyObj:
    def test(self, a=1, b=2, c=3, d=4):
        return [a,b,c,d]

class MyVerboseObj(MyObj):
    def test(self, *args, **kwargs):
        print "RUNNING TEST"   
        return MyObj.test(self, *args, **kwargs)

MyVerboseObj().test()

在此版本中访问a会有点麻烦,但由于您对第二个示例中的参数并不感兴趣,因此这可能是更简单的解决方案。

作为旁注:随着继承结构变得更复杂(即多继承),您可能希望开始使用super()方法:

class MyObj:
    def test(self, a=1, b=2, c=3, d=4):
        return [a,b,c,d]

class MyVerboseObj(MyObj):
    def test(self, *args, **kwargs):
        print "RUNNING TEST"   
        super(MyObj, self).test(*args, **kwargs)

MyVerboseObj().test()