[英]Overriding an inner function of a method in python
这是一种最佳实践问题。
我有一个类结构,定义了一些方法。 在某些情况下,我想覆盖方法的特定部分。 首先想到的是将我的方法拆分为更多原子碎片并覆盖相关部分,如下所示。
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
可能吗?
将_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()
是合理自包含的,你可以创建帮助类AtomicJobParams
和AtomicJobResult
。 使用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
总的来说,这似乎更像是代码分解问题。 瞄准相当精益的课程,在适当的时候将工作委托给帮助者。 遵循单一责任原则 。 如果值属于一起,请将它们捆绑在一个值类中。
正如David Miller(着名的Linux内核开发人员) 最近所说 :
如果您编写的接口包含4个或5个以上的函数参数,那么您和我可能无法成为朋友。
内部变量与它们的定义位置有关,而与它们的执行位置无关。 这打印“你好”。
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()
会得到一个变量的字典,但这被认为是相当糟糕的风格。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.