Algunas veces un objeto puede ser construido por diferentes tipos de argumentos. Por ejemplo, un objeto circular se puede definir proporcionando su radio o su circunferencia. ¿Cómo escribo el método __init__ para que construya un objeto circular tanto cuando el usuario ingresa un radio como cuando ingresa una circunferencia?

Se me ocurrió esto, pero parece demasiado hinchado:

class Circle:

    def __init__(self, radius = None, circumference = None):

        # Calculate area when user provides circumference
        if radius is None and circumference is not None:
            self.area = (circumference**2) / (4*3.14)

        # Calculate area when user provides radius
        elif radius is not None and circumference is None:
            self.area = (radius ** 2) * 3.14

        # Raise error if neither radius nor circumference or both are provided
        else:
            raise TypeError("Pass either a radius or circumference argument value")

¿Configura los parámetros por defecto en None o hay una forma adecuada de Python diseñada para este escenario?

Además, ¿es correcto el uso de TypeError en este caso?

Ni siquiera sé si el radio y la circunferencia se consideran argumentos opcionales o obligatorios aquí, ya que al menos uno de ellos es de alguna manera obligatorio. Alguien puede iluminarme, por favor?

0
multigoodverse 6 feb. 2020 a las 17:32

2 respuestas

La mejor respuesta

Simplemente daría prioridad a uno de los dos argumentos si se proporcionan dos. Sería algo como esto:

class Circle:

    def __init__(self, radius = None, circumference = None):

        # Calculate area when user provides circumference
        if circumference:
            self.area = (circumference**2) / (4*3.14)

        # Calculate area when user provides radius
        elif radius:
            self.area = (radius ** 2) * 3.14

        # Raise error if neither radius nor circumference or both are provided
        else:
            raise TypeError("Pass either a radius or circumference argument value")
2
Ajordat 6 feb. 2020 a las 14:35

Suponiendo que desea que se responda la pregunta del título:

Su código parece estar bien, pero podría usar el parámetro **kwargs en lugar de enumerar todos los posibles candidatos, que pueden verificarse si contienen algo fácilmente sin entrar en detalles.

Para el enfoque general:

Supongo que su desglose de funcionalidad se suma a la complejidad: ¿por qué las cosas de computación en el constructor? Considere esta interfaz:

   c = Circle()
   c.setRadius(4.5) # alternatively: c.setCircumference(13.7)
   print(c.getArea())
1
guidot 6 feb. 2020 a las 15:20