簡體   English   中英

覆蓋python中方法的內部函數

[英]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()是合理自包含的,你可以創建幫助類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

總的來說,這似乎更像是代碼分解問題。 瞄准相當精益的課程,在適當的時候將工作委托給幫助者。 遵循單一責任原則 如果值屬於一起,請將它們捆綁在一個值類中。

正如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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM