0

如果我想将一个相同的 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()

有没有更好的方法将相同的列表参数从 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()

我有很多显示对象,它们具有由不同模块和不同命名约定定义的不同变量——我正在尝试创建具有通用功能的显示对象。

4

2 回答 2

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()
于 2014-08-01T19:49:29.767 回答
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()
于 2014-08-01T20:45:45.293 回答