Python 如何扩展类实例?

Python 如何扩展类实例?,python,class,Python,Class,我有以下代码,这是一个命令行测试 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):

我有以下代码,这是一个命令行测试

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类重命名为_App

那你想在哪里用呢

from blah import _App as App
当你扩展它的时候

from blah import App2 as App

这不是一个精确的解决方案,但它允许您始终通过应用程序名访问它

将App类重命名为_App

那你想在哪里用呢

from blah import _App as App
当你扩展它的时候

from blah import App2 as App

一般来说,这不是一个好主意,因为当人们(包括六个月后的你)阅读代码时,他们会期望
App
是他们知道的类,并且该类的扩展版本会有不同的名称。但是,没有任何东西阻止您将子类命名为与原始类相同的名称:

class App(App):
    # etc.
Python非常聪明,知道括号中的
App
表示它已经知道的类,然后,由于新类具有相同的名称,它将替换原来的类。别担心,新类包含对旧类的引用,因此旧类不会完全消失(如果消失了,子类继承的任何东西都不会起作用)

如果类来自您导入的某个模块,您甚至可以将替换类重新修补到原始模块中,以便导入该模块的所有代码都使用您的替换类。(尽管我会反对!)


当然,这会变得很棘手,因为如果您在脚本中不做第一件事,某些模块可能已经导入了对原始类的引用。如果其他模块也试图修补同一个类,那么所有的麻烦都会被打破。不过,如果您想混淆自己和维护代码的人,Python会让您这么做的

一般来说,这不是一个好主意,因为当人们(包括六个月后的你)阅读代码时,他们会期望
App
是他们知道的类,并且该类的扩展版本会有不同的名称。但是,没有任何东西阻止您将子类命名为与原始类相同的名称:

class App(App):
    # etc.
Python非常聪明,知道括号中的
App
表示它已经知道的类,然后,由于新类具有相同的名称,它将替换原来的类。别担心,新类包含对旧类的引用,因此旧类不会完全消失(如果消失了,子类继承的任何东西都不会起作用)

如果类来自您导入的某个模块,您甚至可以将替换类重新修补到原始模块中,以便导入该模块的所有代码都使用您的替换类。(尽管我会反对!)


当然,这会变得很棘手,因为如果您在脚本中不做第一件事,某些模块可能已经导入了对原始类的引用。如果其他模块也试图修补同一个类,那么所有的麻烦都会被打破。不过,如果您想混淆自己和维护代码的人,Python会让您这么做的

值得注意的是,您可以随时扩充类字典,从而在运行时扩展它

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
的实例,然后查看
\uuu mro\uuuu
(从
类型(yourclass)
开始),直到它到达
对象

因为类是对象,所以可以通过添加属性来扩展它们,然后在属性查找期间可以找到这些属性。请确保执行此操作一次(例如,在导入另一个文件时)

下面是一个真实的例子:

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

值得注意的是,您始终可以扩充类字典,从而在运行时扩展它

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
的实例,然后查看
\uuu mro\uuuu
(从
类型(yourclass)
开始),直到它到达
对象

因为类是对象,所以可以通过添加属性来扩展它们,然后在属性查找期间可以找到这些属性。请确保执行此操作一次(例如,在导入另一个文件时)

下面是一个真实的例子:

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

这是你想要的吗?这是你想要的吗+从纯学术的角度来看,这个答案是金的!尽管事实如此,正如你非常清楚地指出的那样,这在实践中是很糟糕的:从纯学术的角度来看,P+1这个答案是黄金!尽管事实如此,正如你非常清楚地指出的那样,这在实践中是很糟糕的:P