簡體   English   中英

IPython autoreload為重復調用Python2 super()提供錯誤

[英]IPython autoreload gives error for repeated calls to Python2 super()

我正在一個IPython筆記本中的原型,它從我的計算機上的模塊加載Python2代碼。 我激活了重新加載魔術命令,以便在我進行代碼更改並重新運行單元格以查看其影響時,更容易在文本編輯器和筆記本之間來回切換:

%reload_ext autoreload
%autoreload 2

我在Python 2.7.10中工作,因為我使用了一些不能編譯的遺留代碼。我的部分工作是擴展這些遺留代碼中的一些類並重載它們的一些方法。 但是,我還需要調用一些原始的基本方法來完成重要的工作。 例如:

class LegacyBase:

    def important_method(self):
        #old stuff i'll need

class NewClass(LegacyBase):

    #overload base method
    def important_method(self):
       #do some new stuff

       while 1:
           #call old method to do stuff
           super(NewClass, self).important_method() #use old Python2 super calls :(

           #some break conditions

當我第一次在我的筆記本中調用了一些NewClass實例的important_method()時(意味着,在內核重置后),它運行正常。 循環使得super呼叫不止一次發生! 沒有錯誤

但是,如果我在我的文本編輯器中修改一些代碼到我的新方法並返回到IPython單元並再次調用它,我在重載的important_method()中的行中得到以下錯誤,其中進行了super調用。

TypeError: super(type, obj): obj must be an instance or subtype of type

注意:我嘗試將新方法命名為另一個名稱,因為我認為這與重載方法再次調用自身有關,但這沒有用。 此外,我希望它們是相同的名稱,因為這是一個API方法,我希望遺留代碼的用戶能夠調用他們之前知道的相同方法。

知道如何使用這些Python2 super調用在IPython筆記本中重新加載嗎?

謝謝!

您的現有實例仍然指向重新加載之前的舊類。

您需要重新創建實例,或更新其__class__屬性:

instance_of_newclass.__class__ = NewClass

再現問題

我在你的例子之后使用模塊reload_test.py建模:

class LegacyBase:

    def important_method(self):
        print 'doing'

class NewClass(LegacyBase):

    def important_method(self):
        for x in range(3):
            super(NewClass, self).important_method()

在我的IPython筆記本中:

In [1]: %reload_ext autoreload
        %autoreload 2

In [2]: import reload_test

In [3]: nc = reload_test.NewClass()

調用方法會拋出此異常:

In [4]: nc.important_method()

    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-5-09eb0eac244b> in <module>()
    ----> 1 nc.important_method()

    /Users/mike/tmp/reload_test.py in important_method(self)
          9 
         10        for x in range(3):
    ---> 11            super(NewClass, self).important_method()

    TypeError: must be type, not classobj

LegacyBase類需要從object繼承:

class LegacyBase(object):

    def important_method(self):
        print 'doing'

class NewClass(LegacyBase):

    def important_method(self):
        for x in range(3):
            super(NewClass, self).important_method()

現在,我可以重現你的問題。 第一次工作:

In [5]: nc = reload_test.NewClass()

In [6]: nc.important_method()
    doing
    doing
    doing

在編輯器中修改文件后:

class LegacyBase(object):

    def important_method(self):
        print 'doing'

class NewClass(LegacyBase):

    def important_method(self):
        for x in range(3):
            super(NewClass, self).important_method()

調用方法會引發異常:

In [7]: nc.important_method()

     ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    <ipython-input-8-09eb0eac244b> in <module>()
    ----> 1 nc.important_method()

    /Users/mike/tmp/reload_test.py in important_method(self)
          9 
         10        for x in range(3):
    ---> 11            super(NewClass, self).important_method()

    TypeError: super(type, obj): obj must be an instance or subtype of type

只需創建一個新實例:

In [8]: nc = reload_test.NewClass()

In [9]: nc.important_method()
    doing 2
    doing 2
    doing 2

實際上,這意味着只需重新執行包含nc = reload_test.NewClass()的單元格。

可能有點hacky,但我發現在構造函數中將父方法設置為新屬性會啟用自動重新加載。

class LegacyBase:

    def important_method(self):
        #old stuff i'll need

class NewClass(LegacyBase):

    def __init__(self, *args, **kwargs):
        self.__parent_important_method = super(NewClass, self).important_method
        super(NewClass, self).__init__(*args, **kwargs)

    #overload base method
    def important_method(self):
       #do some new stuff

       while 1:
           #call old method to do stuff
           self.__parent_important_method()
           #some break conditions

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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