Создать экземпляр производного класса с экземпляром базового класса?

#python-3.x

#python-3.x

Вопрос:

У меня есть заводской метод для базового класса (A). Ему нужен экземпляр A, чтобы определить, какой производный класс создавать. Каков Pythonic способ сделать это (V3 )?

 class A():

    @classmethod
    def factory(a, b, c):
        foo=A(a,b,c)
        #...use foo to determine that B is the needed subclass.
        return B(foo)

    def __init__(self, a, b, c):
        #  calculations on a, b, c produce several instance attributes
        self.m = calculated_m
        #...
        self.z = calculated_z

class B(A):
    def __init__(self, instance_of_A):
        super(B, self).__init__(?)         # How to construct superclass (A) given an instance of A?
  

Ответ №1:

Вот и все:

 class A():

    @classmethod
    def factory(cls, a, b, c): # first argument of a classmethod is the class on which it's called
        return cls(a, b, c)

    def __init__(self, a, b, c):
        #  calculations on a, b, c produce several instance attributes
        self.m = calculated_m
        #...
        self.z = calculated_z

class B(A):
    def __init__(self, a, b, c):  # example for a subclass with the same signature
        super(B, self).__init__(a, b, c)

class C(A):
    def __init__(self, x, y):  # example for a subclass with different constructor args
        super(B, self).__init__(x y, x*y, 2*x)
    @classmethod
    def factory(cls, x, y):
        return cls(x, y)
  

Использование:

 foo = A.factory(a, b, c)  # this will call A.factory
bar = B.factory(a, b, c)  # this also
baz = C.factory(x, y)  # this will call C.factory
  

Может быть, вы можете переименовать factory метод в get_instance , потому что фабрики обычно являются классами, предназначенными для создания объектов других классов.

Напишите комментарий, если у вас все еще есть вопросы

Комментарии:

1. Спасибо за ответ и спасибо за информацию о ‘cls’. Я относительно новичок в Python, как вы, возможно, догадались. Что касается подкласса, я не сформулировал вопрос четко. Я надеялся, что конструктор для B будет использовать экземпляр A (вместо отдельных атрибутов A). Проблема в том, что A имеет много атрибутов. Передача их по отдельности увеличивает нагрузку на программу и визуальное загрязнение исходного кода. Есть ли способ создать экземпляр B с экземпляром A?

2. @SmarteePantz почему A должен знать о B? softwareengineering.stackexchange.com/questions/219543 /…

3. Спасибо за комментарий. Вместо «знания» B я на самом деле хочу, чтобы конструктору B был передан экземпляр A. Имеет ли вопрос больше смысла с этим разъяснением?