2013-02-25 112 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