覆盖python中方法的内部函数

时间:2015-05-22 10:12:51

标签: python python-2.6 method-overriding

这是一种最佳实践问题。

我有一个定义了一些方法的类结构。在某些情况下,我想覆盖方法的特定部分。首先想到的是将我的方法拆分为更多原子碎片并覆盖相关部分,如下所示。

class myTest(object):
    def __init__(self):
        pass

    def myfunc(self):
        self._do_atomic_job()
        ...
        ...

    def _do_atomic_job(self):
        print "Hello"

这是解决问题的实用方法。但由于我有太多的参数需要转移到_do_atomic_job()并从self.param_var恢复,我不想传递和检索大量的参数。其他选项是将这些参数设置为具有self等的类变量,但这些参数仅用于代码的一小部分,使用class MyTest2(object): mytext = "" def myfunc(self): def _do_atomic_job(): mytext = "Hello" _do_atomic_job() print mytext 不是我解决此问题的首选方法。

我认为最后一个选项是使用内部函数。 (我知道我会在变量范围内遇到问题,但正如我所说,这是一种最佳实践,只是忽略它们并认为范围和内部函数的所有内容都按预期工作)

_do_atomic_job()

让我们假设按预期工作。我想要做的是重写内部函数class MyTest3(MyTest2): def __init__(self): super(MyTest3, self).__init__() self.myfunc._do_atomic_job = self._alt_do_atomic_job # Of course this do not work! def _alt_do_atomic_job(self): mytext = "Hollla!"

_do_atomic_job

我想要实现的是覆盖继承的类'方法的内部函数{{1}}

有可能吗?

2 个答案:

答案 0 :(得分:3)

_do_atomic_job()分解为正确的方法,或者可能将其分解 进入自己的班级似乎是最好的方法。压倒一个内心 函数无法工作,因为你无法访问该函数的局部变量 包含方法。

你说_do_atomic_job()需要很多参数才能返回很多值。也许您将其中一些参数分组到合理的对象中:

_do_atomic_job(start_x, start_y, end_x, end_y) # Separate coordinates
_do_atomic_job(start, end)                     # Better: start/end points
_do_atomic_job(rect)                           # Even better: rectangle

如果你不能这样做,_do_atomic_job()是合理自足的, 您可以创建帮助程序类AtomicJobParamsAtomicJobResult。 使用namedtuples而不是类的示例:

AtomicJobParams = namedtuple('AtomicJobParams', ['a', 'b', 'c', 'd'])

jobparams = AtomicJobParams(a, b, c, d)
_do_atomic_job(jobparams)                # Returns AtomicJobResult

最后,如果原子作业是自包含的,你甚至可以将其纳入其中 自己的班级AtomicJob

class AtomicJob:
    def __init__(self, a, b, c, d):
        self.a = a
        self.b = b
        self.c = c
        self.d = d
        self._do_atomic_job()

    def _do_atomic_job(self):
        ...
        self.result_1 = 42
        self.result_2 = 23
        self.result_3 = 443

总的来说,这似乎更像是代码分解问题。瞄准相当精益 在适当的情况下将工作委派给助手的类。关注single responsibility principle。如果值属于一起,请将它们捆绑在一个值类中。

David Miller(着名的Linux内核开发人员)recently said

  

如果您编写的接口包含4个或5个以上的函数参数,那么就是这样   可能你和我不能成为朋友。

答案 1 :(得分:0)

内部变量与定义它们的位置有关,而与它们的执行位置无关。这打印“你好”。

class MyTest2(object):
    def __init__(self):
        localvariable = "hello"
        def do_atomic_job():
            print localvariable
        self.do_atomic_job = do_atomic_job

    def myfunc(self):
        localvariable = "hollla!"
        self.do_atomic_job()


MyTest2().myfunc()

所以我看不到任何方式你可以使用局部变量而不传递它们,这可能是最好的方法。

注意:传递locals()会让你知道变量,但这被认为是非常糟糕的风格。