@firstmixon

Вопрос по конструктору класса?

Возможно ли в Питоне, кроме базавого конструктора __init__(self) создать конструкток который в виде параметра будет получать экземпляр данного класса и инициализировать свойства создаваемого зкземпляра данными из переданного эклемпляра?

Подскажите что я делаю не так?
class test:
    zzz:int;

    def __init__(self):
        self.zzz=123;

    def __init__(self, x:test//как тут передать ссылку на экземпляр?):
        self.zzz=x.zzz;

    def add(c:int):
        zzz += c
  • Вопрос задан
  • 155 просмотров
Пригласить эксперта
Ответы на вопрос 3
Vindicar
@Vindicar
RTFM!
К сожалению, functools.singledispatchmethod тут не поможет, так как он не справляется с аргументами-экземплярами того же класса.
Ты можешь проверять переданные аргументы вручную...

import typing as tp


class Test:
    @tp.overload
    def __init__(self, x: int, y: str):
        ...  # тут не должно быть тела!

    @tp.overload
    def __init__(self, other: 'Test'):
        ...  # typehint в виде строки, так как класс Test еще не создан. Тела нет!

    def __init__(self, *args, **kwargs):  # настоящий конструктор
        # определяем, как нас вызвали
        if 'other' in kwargs:
            first_arg = kwargs['other']
            x, y = first_arg.x, first_arg.y
        elif 'x' in kwargs:
            x, y = kwargs.get('x'), kwargs.get('y')
        elif isinstance(args[0], Test):
            x, y = args[0].x, args[0].y
        else:
            x, y = args[0:2]
        self.x: int = x
        self.y: str = y

    def __repr__(self) -> str:
        return f'Test(x={self.x!r}, y={self.y!r})'

# порядковая передача аргументов сработает
t1 = Test(1, 'foo')
t2 = Test(t1)
print(t1, t2)
# именованная передача аргументов сработает
t3 = Test(x=2, y='bar')
t4 = Test(other=t3)
print(t3, t4)

Test(3, y='baz')  # а вот это сломается...

Но у тебя будет куча проблем с аргументами имеющими значение по умолчанию.
Метод copy() будет куда практичнее и понятнее.
Ответ написан
Комментировать
plustilino
@plustilino
https://younglinux.info
Два конструктора создать можно, но работать будет только последний:
>>> class A:
...     def __init__(self):
...             print(1)
...     def __init__(self, n=3):
...             print(n)
... 
>>> a = A()
3
Ответ написан
Комментировать
@Jack444
class test:
    zzz: int
  
     def __init__(self, zzz: int = 123, obj: 'test' = None):
         self.zzz = obj.zzz if obj else zzz
 
     def add(self, c: int):
         self.zzz += c
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы