Tengo una función que espera dos valores de corte, llamado min_df y max_df. Cualquiera puede ser un int para referirse a una frecuencia absoluta de corte, o un float para denotar una frecuencia relativa. Ahora, quiero añadir algunas comprobaciones y dar mensajes de advertencia, pero sin demasiado alboroto. Esto funciona:

if max_df < 0 or min_df < 0:
    raise ValueError, "neither max_df (%s) nor min_df (%s) may be <0" %
                      (max_df, min_df)

pero con un float como (1/3.), la advertencia contiene 0.333333333333. Prefiero tener que decir 0.333, así que traté de %.3f, pero que se convierte int valores en carrozas así y muestra 2.000 para 2.

¿Cómo puedo cambiar el tipo para obtener el formato correcto? Qué necesito para construir la cadena de formato antes de pasar a la % operador?

Actualización: necesito algo que funciona en Python 2.5, ya que es la versión mínima de la que estoy apuntando.

De decidir entre la absoluta y la relativa basado en el tipo numérico suena como algo que violaría el principio de la menor sorpresa. Yo uso un booleano palabra clave argumento relative=False o algo a cambio.
El problema es que hay dos parámetros de corte que trabajar de esta manera, y más pueden ser implementadas, así que necesitaría el doble del número de parámetros.
Creo que @grep método es el camino a seguir, pero se puede hacer algo difícil con anidada especificadores en una nueva versión de Python — int_fl = lambda num: '' if isinstance(num, int) else '.3f' luego print "Neither max_df ({:{}}) nor min_df ({:{}}) may be negative.".format(max_df, int_fl(max_df), min_df, int_fl(min_df))
¿Qué pensar entonces de un par de envoltorio clases? Así que se podría llamar como foo(Absolute(1), Relative(2), Absolute(3)). Entonces, usted puede mover el punto de corte de la lógica en ellos y utilizar polimorfismo más que en un despacho sobre los tipos de argumento.
Estoy de acuerdo que no se debe usar el tipo de distinguir, podría subclase int y float y agregar un atributo de clase relative = False y relative = True respectivamente, por lo que puede diferenciarlos con if max_df.relative

OriginalEl autor Fred Foo | 2011-09-19

2 Comentarios

  1. 8

    Keep it simple

    def format_df(df):
        if isinstance(df, (int, long)):
            return "%d" % df
        elif isinstance(df, float):
            return "%.3f" % df
        else:
            return str(df) # fallback just in case
    
    raise ValueError, "neither max_df (%s) nor min_df (%s) may be <0" %
                      (format_df(max_df), format_df(min_df))

    OriginalEl autor grep

  2. 5

    Cómo sobre esto:

    >>> "{:.4g}".format(1)
    '1'
    >>> "{:.4g}".format(1.3)
    '1.3'
    >>> "{:.4g}".format(1.333)
    '1.333'
    >>> "{:.4g}".format(1.333333)
    '1.333'

    Sin embargo (desde el 4 dígitos significativos también incluyen la parte entera) había también conseguir esto:

    >>> "{:.4g}".format(10.333)
    '10.33'
    >>> "{:.4g}".format(10000)
    '1e+04'
    El g especificador sería agradable si no se muestra 1. como 1. La diferencia entre int y float es crucial.

    OriginalEl autor Tim Pietzcker

Dejar respuesta

Please enter your comment!
Please enter your name here