Условные типы, инициализированные в Python - PullRequest
1 голос
/ 11 марта 2020

Я пытаюсь написать свой собственный класс "дроби", который принимает два числовых объекта: числитель и знаменатель. Однако, в зависимости от типа данных для двух аргументов, я хотел бы, чтобы объект инициализировался различными способами.

Например, если я объявляю x = Frac(2,5), я хочу, чтобы x оставался Frac тип. Принимая во внимание, что если я объявляю y = Frac(2.1, 5), я хочу, чтобы y был приведен к float со значением 0,42, а не Frac(21,50).

Что было бы правильным путем для go о чем-то как это?

Это похоже на сценарий, в котором кортеж с одним объектом просто возвращает исходный объект. Это означает, что x = ("cat") устанавливает x тип str, а не тип tuple.

1 Ответ

4 голосов
/ 11 марта 2020

Есть два варианта.

1. Фабричный метод

x = Frac.create_by_type(2, 5)
y = Frac.create_by_type(2.1, 5)

Пример реализации:

class Frac:
    ...
    @classmethod
    def create_by_type(cls, a, b):
        if isinstance(a, float):
            return a / b
        return cls(a, b)

Если вы хотите использовать конструктор Frac напрямую,

2. Переопределение Frac.__new__ метода

class Frac:
    def __new__(cls, a, b):
        if isinstance(a, float):
            return a / b
        return super().__new__(cls)

    def __init__(self, a, b):
        self.a = a
        self.b = b


f1 = Frac(2, 5)
f2 = Frac(2.1, 5)

print(type(f1))
print(type(f2))
print(f1.a, f1.b)

output:

<class '__main__.Frac'>
<class 'float'>
2 5

Но переопределение __new__ метода может быть сложным, поэтому я не уверен, что рекомендую его.

...