给定基础对象创建派生对象

时间:2018-06-18 14:51:55

标签: python inheritance

我有一个基类,其__init__有两个参数。我想创建一个派生类对象,因为我有一个基类对象。 我想做以下事情,

a_obj = A(10, 'f') 
## given that I have a_obj, create b_obj
b_obj = B(a_obj)

并得到一个结果

type(b_obj) => B

print(b_obj.age) => 10
print(b_obj.sex) => "f"

我尝试了以下内容,其中B的__new__将调用A __new__并要求它创建类型为B的对象(空对象)。但在这一点上,我不知道如何设置B具有A的所有功能。

class A:
  def __init__(self, age, sex):
    self.age = age
    self.sex = sex

class B(A):
  def __new__(cls, a_obj):
    a_class = a_obj.__class__
    b_obj = a_class.__new__(cls)
    a_class.__init__(b_obj, a_obj) #doesnt work since A's init takes 2 params

有没有比将给定A的对象强制转换为B更好的方法? (即a_obj.__classs__ = b_obj

修改   B是动态创建的类(使用类型)。所以B事先不知道A __init__会采取什么参数。

4 个答案:

答案 0 :(得分:2)

很简单,将html_soup.find_all("li", class_='stat product_avguserscore')a_object.age传递给父构造函数。

a_object.sex

现在请注意,人们通常希望子类与其父类兼容,而这种情况并非如此。

编辑:回答其他问题“如果B是动态生成的,并且事先不知道A的 init 将采用什么参数”,那么规范的解决方案是使用varargs和关键字ARGS:

class A(object):
  def __init_(self, age, sex):
    self.age = age
    self.sex = sex

class B(A):
  def __init__(self, a):
      super(B, self).__init__(a.age, a.sex)

答案 1 :(得分:1)

通过在super

的调用中传递a的属性,这是一种简单的方法
class A:
  def __init__(self, age, sex):
      self.age = age
      self.sex = sex

class B(A):
    def __init__(self, a):
         """a is an instance of A"""
         super().__init__(a.age, a.sex)

回答"如果B是动态生成的类怎么办? B不知道A&#39的参数是什么",这要困难得多,并且需要一些真正的python黑客攻击。

class B(A):
    def __init__(self, a):
        self.__dict__.update(a.__dict__)

我不认可这样做。这是糟糕的编码实践,可能容易出错。

答案 2 :(得分:0)

嗯,通过示例,不清楚继承是否将用于属性访问以外的任何目的。 如果获取所有对象字段只是你想要的东西,我想,它没有必要使用继承。

因为python中的每个对象都有dict属性,所以你可以复制它:

class A:
    def __init__(self, age, sex):
        self.age = age
        self.sex = sex

class B:
    def __init__(self, a_obj):
        self.__dict__ = a_obj.__dict__.copy()

if __name__ == "__main__":
    a_obj = A(10, "f")
    b_obj = B(a_obj)

    print(type(b_obj)) # B

    # Works as expected.
    print(b_obj.age)
    print(b_obj.sex)

尽管提供的示例与继承一样可行,但在这种情况下,我几乎不建议使用如上所述的父构造函数。

答案 3 :(得分:-2)

可能在B级中使用getattr

class B:
    def __init__(self, a_object):
        self._a = a_object

    def __getattr__(self, item):
        return getattr(self._a, item)

因此,如果b_obj没有age属性,则会引用age中的a_object