2013-02-25 213 views
0

我有下面的代碼,這是一個命令行測試如何擴展類實例?

from cmd2 import Cmd 
class App(Cmd, object): 
    def __init__(self, *args, **kwargs): 
      pass 

    def do_test(self, line): 
     'test' 
     print "parent test" 


class App2(): 
    def __init__(self, *args, **kwargs): 
      pass 

    def do_test2(self, line): 
     print "Test2"   


app = App() 
app.cmdloop() 

是否有額外的功能擴展App類的可能性? 我知道有以下解決方案

class App2(App): 
    .... 

app = App2() 
app.cmdloop() 

但對我來說,我想只運行App,並延長它,如果它是可能的。

+0

這是你想要的嗎? http://stackoverflow.com/questions/972/adding-a-method-to-an-existing-object – 2013-02-25 21:39:58

回答

1

值得注意的是,您始終可以擴充類字典,因此可以在運行時對其進行擴展。

class App(...): 
    def __init__(self, a, b): 
    pass 

    def do_something(self, a): 
    pass 


app_instance = App() 


def do_something_else(self, b): 
    pass 

App.do_something_else = do_something_else 


app_instance.do_something_else('b') 

你必須考慮python在運行時如何進行查找。首先查看yourclass的實例,然後查看__mro__(從type(yourclass)開始),直到達到object

由於類是ARE對象,因此可以通過添加屬性來擴展它們,這些屬性將在屬性查找期間找到。確保你這樣做(例如,在導入另一個文件的過程中)。

下面是一個真實的例子:

>>> class foo(): 
...  pass 
... 
>>> x = foo() 
>>> 
>>> # Define a function and attach it 
>>> 
>>> def bar(self, a): 
...  print(a) 
... 
>>> foo.bar = bar 
>>> 
>>> x.bar('a') 
a 
0

這個心不是一個確切的解決方案,但它可以讓你隨時通過應用程序名稱

重命名App類,你想用它

from blah import _App as App 

,當你訪問它_App

然後擴展它

from blah import App2 as App 
5

一般來說這不是一個好主意,因爲當人們(包括你在六個月內)閱讀代碼,他們會認爲App是他們瞭解的類,並且該類的擴展版本具有不同的名稱。然而,沒有什麼阻止你命名的子類和原來一樣:

class App(App): 
    # etc. 

Python的足夠聰明,知道括號中的App意味着它已經知道的一個,然後,因爲新的類有同名,它取代原來的一個。別擔心,新類包含對舊類的引用,所以舊類不會完全消失(如果是這樣,則子類繼承的任何東西都不會起作用)。

如果這個類來自您導入的某個模塊,您甚至可以將替換類修補回原始模塊,以便導入該模塊的所有代碼都使用替換類。 (雖然我不推薦它!)

import appmodule 

class App(appmodule.App): 
    # etc. 

appmodule.App = App 

當然,這得到棘手,因爲有些模塊可能已經進口到原來的類的引用,如果你沒有在你的腳本做的第一件事。而如果其他模塊也試圖修補相同的類,所有地獄都可能破裂。不過,如果你想讓自己和那些會維護你的代碼的人混淆,Python會讓你做到這一點!

+1

+1爲重複「這是一個壞主意......但如果你想足夠的繩子...... 「 – 2013-02-25 21:35:29

+0

+1從純粹的學術觀點來看,這個答案是金子!儘管如此,正如你清楚地表明的那樣,這在實踐中會很差:P – 2017-07-11 23:16:15