Python:可以从父类实例构造子类实例吗?

6 投票
6 回答
1922 浏览
提问于 2025-04-16 21:09

这可能是个糟糕的主意(如果是的话,欢迎告诉我),但我正在探索Python的边界,我觉得这可能会有用(实际上,我现在正考虑一个潜在的应用场景)。

这里是我的设置:

---(API文件)---

class APINode(object):
    def __init__(self, *args, **kwargs):
        # initialize some instance variables

    def render(self, arg1, arg2):
        # do some stuff and return something

def api_function( arg1, arg2 ):
    # do some stuff
    return APINode(args, kwargs)

----(我的文件)----

class MyNode(APINode):
    def render(self, arg1, arg2):
        #My override of APINode's render 


def my_function( arg1, arg2 ):
    api_parent_instance = api_function( arg1, arg2 )
    #Can I some how create an instance of MyNode from api_parent_instance here?

我想稍微修改一下api_function的输出,基本上就是覆盖它返回的对象中的render函数。我觉得我有两个选择:(1,真糟糕)把api_function的内容复制到my_function中,但只构造并返回一个MyNode,而不是APINode,或者(2,也许?)直接在my_function中调用api_function,让它完成工作——构造并返回一个APINode类型的对象,然后我可以以某种方式从那个对象创建一个MyNode,以便覆盖那个方法。

归根结底:在Python中,是否可以从父类的实例构造一个子类的实例?

(看起来熟悉,或者想知道实际情况是什么?我正在尝试扩展一个Django模板标签。)

6 个回答

1

重写分配器。

class B(object):
  def __new__(cls, val):
    if val:
      return D()
    return super(B, cls).__new__(cls)

  def foo(self):
    return 'bar'

class D(object):
  def foo(self):
    return 'baz'

b1 = B(False)
b2 = B(True)
print b1.foo()
print b2.foo()
2

在家里不要这样做。

>>> class A:
...     def hi(self):
...         print "I am an A!"
... 
>>> class B:
...     def hi(self):
...         print "I am a B!"
... 
>>> a = A()
>>> a.hi()
I am an A!
>>> # Doing this will likely lead to hard to find bugs.
>>> a.__class__ = B
>>> a.hi()
I am a B!
>>> 

不如直接修改API吧!

def render(self, arg1, arg2):
    #My override of APINode's render 
APINode.render = render
#congratulations, now APINode uses your render function.

这样做可能还是会出现难以发现的错误,但看起来会干净一些。

7

我觉得用MyNode来包裹APINode会让你更开心,而不是直接扩展它。你可以自己实现一个render()方法,然后把其他所有方法都交给被包裹的APINode去处理。这样你就能从现有的APINode创建一个新的MyNode。

从父实例创建子实例是不可能的。父实例是APINode的一个实例,你不能改变一个对象的类型。

撰写回答