覆盖 python 中方法的内部函数
Overriding an inner function of a method in python
这是一种最佳实践问题。
我有一个 class 结构,其中定义了一些方法。在某些情况下,我想重写方法的特定部分。首先想到的是将我的方法拆分为更多原子部分并覆盖相关部分,如下所示。
class myTest(object):
def __init__(self):
pass
def myfunc(self):
self._do_atomic_job()
...
...
def _do_atomic_job(self):
print "Hello"
这是一个看起来很实用的解决问题的方法。但是由于我有太多参数需要传输到 _do_atomic_job()
并从 _do_atomic_job()
返回,我不想传递和检索大量参数。其他选项是将这些参数设置为 class 变量和 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!"
做我想实现的是覆盖继承的class'方法的内部函数_do_atomic_job
可能吗?
要么将 _do_atomic_job()
分解为适当的方法,要么将其分解
进入它自己的 class 似乎是最好的方法。覆盖内部
函数无法工作,因为您无权访问
包含方法。
你说 _do_atomic_job()
需要很多参数 returns 很多值。也许您将其中一些参数分组为合理的对象:
_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()
是相当独立的,
您可以创建助手 classes AtomicJobParams
和 AtomicJobResult
。
使用 namedtuples
而不是 classes 的示例:
AtomicJobParams = namedtuple('AtomicJobParams', ['a', 'b', 'c', 'd'])
jobparams = AtomicJobParams(a, b, c, d)
_do_atomic_job(jobparams) # Returns AtomicJobResult
最后,如果原子作业是独立的,您甚至可以将其纳入其
拥有 class 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
总的来说,这更像是一个代码分解问题。力求瘦身
class在适当的时候将工作委派给助手。关注single responsibility principle。如果值属于一起,将它们捆绑在一个值 class.
中
作为 David Miller(著名的 Linux 内核开发人员)recently said:
If you write interfaces with more than 4 or 5 function arguments, it's
possible that you and I cannot be friends.
内部变量与它们的定义位置有关,与它们的执行位置无关。这会打印 "hello".
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()
会给你一个变量的字典,虽然这被认为是很糟糕的风格。
这是一种最佳实践问题。
我有一个 class 结构,其中定义了一些方法。在某些情况下,我想重写方法的特定部分。首先想到的是将我的方法拆分为更多原子部分并覆盖相关部分,如下所示。
class myTest(object):
def __init__(self):
pass
def myfunc(self):
self._do_atomic_job()
...
...
def _do_atomic_job(self):
print "Hello"
这是一个看起来很实用的解决问题的方法。但是由于我有太多参数需要传输到 _do_atomic_job()
并从 _do_atomic_job()
返回,我不想传递和检索大量参数。其他选项是将这些参数设置为 class 变量和 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!"
做我想实现的是覆盖继承的class'方法的内部函数_do_atomic_job
可能吗?
要么将 _do_atomic_job()
分解为适当的方法,要么将其分解
进入它自己的 class 似乎是最好的方法。覆盖内部
函数无法工作,因为您无权访问
包含方法。
你说 _do_atomic_job()
需要很多参数 returns 很多值。也许您将其中一些参数分组为合理的对象:
_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()
是相当独立的,
您可以创建助手 classes AtomicJobParams
和 AtomicJobResult
。
使用 namedtuples
而不是 classes 的示例:
AtomicJobParams = namedtuple('AtomicJobParams', ['a', 'b', 'c', 'd'])
jobparams = AtomicJobParams(a, b, c, d)
_do_atomic_job(jobparams) # Returns AtomicJobResult
最后,如果原子作业是独立的,您甚至可以将其纳入其
拥有 class 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
总的来说,这更像是一个代码分解问题。力求瘦身 class在适当的时候将工作委派给助手。关注single responsibility principle。如果值属于一起,将它们捆绑在一个值 class.
中作为 David Miller(著名的 Linux 内核开发人员)recently said:
If you write interfaces with more than 4 or 5 function arguments, it's possible that you and I cannot be friends.
内部变量与它们的定义位置有关,与它们的执行位置无关。这会打印 "hello".
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()
会给你一个变量的字典,虽然这被认为是很糟糕的风格。