[英]Convert superclass instance to subclass instance
有沒有標准和簡單的方法來做到這一點?
# I cannnot tweak these code
def genA():
a = A
return(a)
class A:
def __init__():
self.a = 1
# ---
# code in my side
class B(A):
def __init__():
self.b = 2
a = genA()
# like a copy-constructor, doesn't work
# b = B(a)
# I want to get this
b.a # => 1
b.b # => 2
這是一個等效的c ++代碼:
#include <iostream>
// library side code
class A {
public:
int a;
// ... many members
A() { a = 1; }
};
void fa(A a) {
std::cout << a.a << std::endl;
}
A genA() { A a; return a; }
// ///
// my code
class B : public A {
public:
int b;
B() : A() { init(); }
B(A& a) : A(a) { init(); }
void init() { b = 2; }
};
void fb(B b) {
std::cout << b.b << std::endl;
}
int main(void) {
A a = genA();
B b(a);
fa(b); // => 1
fb(b); // => 2
}
你不應該用__new__
,但它只適用於新式的類:
class A(object):
def __init__(self):
self.a = 10
class B(A):
def __new__(cls, a):
a.__class__ = cls
return a
def __init__(self, a):
self.b = 20
a = A()
b = B(a)
print type(b), b.a, b.b # <class '__main__.B'> 10 20
但正如我所說,不要這樣做,你應該使用聚合 ,而不是在這種情況下的子類。 如果您希望生成B
,那么它將具有與A
相同的接口,您可以使用__getattr__
編寫透明代理:
class B(object):
def __init__(self, a):
self.__a = a
self.b = 20
def __getattr__(self, attr):
return getattr(self.__a, attr)
def __setattr__(self, attr, val):
if attr == '_B__a':
object.__setattr__(self, attr, val)
return setattr(self.__a, attr, val)
我不明白你的代碼。 IMO不正確。 首先,在A和B中__init__
中沒有self。其次,在你的B類中,你不是在調用A的構造函數。 第三,genA不返回任何對象,只是引用A類。 請檢查更改的代碼:
def genA():
a = A() #<-- need ()
return(a)
class A:
def __init__(self): # <-- self missing
self.a = 1
# ---
# code in my side
class B(A):
def __init__(self, a=None):
super().__init__() #<-- initialize base class
if isinstance(a, A): #<-- if a is instance of base class, do copying
self.a = a.a
self.b = 2
a = genA()
a.a = 5
b = B(a)
# this works
print(b.a) # => 5
print(b.b) # => 2
似乎沒有一種標准的方法,但有幾種方法。 如果您不想處理每個屬性,我建議如下:
class A(object):
# Whatever
class B(A):
def __init__(self, a):
super(B, self).__init__()
for attr in dir(a):
setattr(self, attr, getattr(a, attr))
# Any other specific attributes of class B can be set here
# Now, B can be instantiated this way:
a = A()
b = B(a)
如果您不想訪問父級的“私有”屬性,可以添加
if not attr.startswith('__'):
在for
循環。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.