Python: как "объединить" два класса
Я хочу добавить некоторые атрибуты и методы в различного класса. Методы и атрибуты, которые я должен добавить, одинаковы, но не класс для их назначения, поэтому я хочу создать класс, который назначает новые методы и атрибут для класса, заданного в аргументе. Я пытаюсь, но ничего не получается.: (Я знаю, что это очень неправильный способ попытаться назначить что-то себе, это просто показать, что я хочу сделать)
class A:
def __init__(self):
self.a = 'a'
def getatt(self):
return self.a
class B:
def __init__(self, parent) :
self = parent
# This is working :
print self.getatt()
def getattB(self):
return self.getatt()
insta = A()
instb = B(insta)
# This is not working :
print instb.getattB()
результат :
a
Traceback (most recent call last):
File "D:Documents and settingsBureaumerge.py", line 22, in <module>
print instb.getattB()
File "D:Documents and settingsBureaumerge.py", line 16, in getattB
return self.getatt()
AttributeError: B instance has no attribute 'getatt'
и я ожидал получил " а " за вызов instb.gettattB ()
чтобы возобновить, я хочу наследовать класс B от класса A, давая класс A в аргументе класса B, потому что мой класс B будет подклассом различного класса, а не всегда A.
5 ответов
лучший ответ в комментариях, это было полезно для меня, поэтому я решил показать его в ответе (спасибо sr2222): Путь к динамично объявить inherance в Python-это тип() встроенная функция. Для моего примера :
class A(object) :
def __init__(self, args):
self.a = 'a'
self.args = args
def getattA(self):
return self.a, self.args
class B(object) :
b = 'b'
def __init__(self, args) :
self.b_init = args
def getattB(self):
return self.b
C = type('C', (A,B), dict(c='c'))
instc = C('args')
print 'attributes :', instc.a, instc.args, instc.b, instc.c
print 'methodes :', instc.getattA(), instc.getattB()
print instc.b_init
код :
attributes : a args b c
methodes : ('a', 'args') b
Traceback (most recent call last):
File "D:\Documents and settings\Bureau\merge2.py", line 24, in <module>
print instc.b_init
AttributeError: 'C' object has no attribute 'b_init'
My class C inerhite атрибуты и методы класса A и класса B, и мы добавляем атрибут C. С экземпляром C (instc = C ('args'))init для вызова is, но не для Б.
очень полезно для меня, потому что я должен добавить некоторые атрибуты и методы (то же самое) в другом классе.
Я не уверен, что вы пытаетесь сделать, но код ниже дает мой вывод я думаю вы ожидаете. обратите внимание:
- a инициализируется вне конструктора в
- B объявляется как подкласс a
код:
class A:
a='' #Initialize a
def __init__(self):
self.a = 'a'
def getatt(self):
return self.a
class B(A): #Declare B as subclass
def __init__(self, parent) :
self = parent
print self.getatt()
def getattB(self):
return self.getatt()
insta = A()
instb = B(insta)
print instb.getattB()
Как насчет этого?
class A:
def __init__(self):
self.a = 'a'
def getatt(self):
return self.a
class B:
def __init__(self, parent) :
self.parent = parent
def __getattr__(self, attr):
return getattr(self.parent, attr)
def getattB(self):
return self.parent.getatt()
insta = A()
instb = B(insta)
print instb.getattB()
print instb.getatt()
но метод в классе A не может получить доступ к attr в классе B.
иначе:
import functools
class A:
def __init__(self):
self.a = 'a'
def getatt(self):
return self.a
class B:
def __init__(self, parent):
for attr, val in parent.__dict__.iteritems():
if attr.startswith("__"): continue
self.__dict__[attr] = val
for attr, val in parent.__class__.__dict__.iteritems():
if attr.startswith("__"): continue
if not callable(val): continue
self.__dict__[attr] = functools.partial(val, self)
def getattB(self):
return self.getatt()
insta = A()
instb = B(insta)
print instb.__dict__
print instb.getattB()
print instb.getatt()
медленно с init но вызвать "скорую".
у меня возникли проблемы с вызовом разных конструкторов, используя super
Не обязательно имеет смысл в таком случае, я решил наследовать и вызывать каждый конструктор для текущего объекта вручную:
class Foo(object):
def __init__(self, foonum):
super(Foo, self).__init__()
self.foonum = foonum
class Bar(object):
def __init__(self, barnum):
super(Bar, self).__init__()
self.barnum = barnum
class DiamondProblem(Foo, Bar):
# Arg order don't matter, since we call the `__init__`'s ourself.
def __init__(self, barnum, mynum, foonum):
Foo.__init__(self, foonum)
Bar.__init__(self, barnum)
self.mynum = mynum