2010-05-31 8 views
19

que tienen un sistema de análisis de registros de texto de longitud fija sobre la base de una tabla de diseño:Cómo hacer "int" analizar cadenas en blanco?

parse_table = [\ 
    ('name', type, length), 
    .... 
    ('numeric_field', int, 10), # int example 
    ('textc_field', str, 100), # string example 
    ... 
] 

La idea es que dada una mesa para un tipo de mensaje, acabo de ir a través de la cadena, y reconstruir un diccionario a cabo de ella, según las entradas en la tabla.

Ahora, puedo manejar cadenas y enteros correctos, pero int() no analizará todos los campos de espacios (por una buena razón, por supuesto).

Quería manejarlo definiendo una subclase de int que maneja cadenas en blanco. De esta manera podría ir y cambiar el tipo de entradas de tabla apropiadas sin introducir kludges adicionales en el código de análisis sintáctico (como filtros), y simplemente "funcionaría".

Pero no puedo imaginar cómo anular el constructor de un tipo de compilación en un subtipo, ya que definir el constructor en la subclase no parece ayudar. Siento que aquí me falta algo fundamental sobre cómo funcionan los tipos incorporados de Python.

¿Cómo debo abordar esto? También estoy abierto a alternativas que no agregan demasiada complejidad.

+0

+1 ... Estoy tratando de hacer algo ligeramente parecido en mi proyecto ... actualmente, en lugar de tomar "tipos", tomo las funciones que devuelven el tipo apropiado. Por lo tanto, puede manejar cadenas en blanco y * luego * devolver un int. – mpen

+1

Intente reemplazar la función int por una que desee usar en su lugar. – Arafangion

+0

¿Cómo maneja los campos de cadena de longitud fija? ¿Dejando el espacio en blanco al final allí? –

Respuesta

27

Utilice una función de la fábrica en vez de int o una subclase de int:

def mk_int(s): 
    s = s.strip() 
    return int(s) if s else 0 
+0

NO sabía que podría haber condicionales expuestos después de una devolución. ¡Gracias! –

+2

@ DominicBou-Samra "a if b else c" es la versión de Python del operador ternario, que se ve como "b? A: c" en muchos otros idiomas. No hay ninguna condición aquí "después de un regreso". la expresión ternaria se evalúa * antes * de la declaración de devolución. –

6
lenient_int = lambda string: int(string) if string.strip() else None 
                  #else 0 
                  #else ??? 
+0

¿Qué quiere que suceda cuando obtiene una cadena vacía, exactamente? – badp

+0

s/trim/strip/tal vez –

+0

¡Vaya! Gracias :) – badp

0

nota que milista es una lista que contiene:

tuplas, y en el interior tuplas, hay I) valores nulos/vacíos, ii) dígitos, números como cadenas, así como iii) listas vacías/nulas. por ejemplo:

mylist=[('','1',[]),('',[],2)] 

@Arlaharen estoy repitiendo aquí, su solución, de manera algo diferente, con el fin de añadir palabras clave, porque, he perdido mucho tiempo, con el fin de encontrar!

La siguiente solución es stripping/convertir cadenas nulas, cadenas vacías o listas vacías, como cero, PERO conserva cadenas no vacías, listas no vacías, que incluyen dígitos/números como cadenas, y luego convierte estas cadenas , como números/dígitos.

Solución simple. Tenga en cuenta que "0" puede ser reemplazado por variables iterables. Tenga en cuenta que la primera solución no puede TRATAR listas vacías dentro de tuplas.

int(mylist[0][0]) if mylist[0][0].strip() else 0 

me pareció aún más forma más simple, que puede tratar listas vacías en una tupla

int(mylist[0][0] or '0') 

cadena convertido a dígitos/convertir cadena a número/convertir una cadena a entero tira listas vacías/franja cadena vacía/tratar cadena vacía como dígito/número convertir cadena nula como dígito/número/convertir cadena nula como número entero

4

Puede usar la función int() con el argumento s.strip() or 0, yo.e:

int(s.strip() or 0) 

Si s.strip() evalúa al valor Falsy (como es el caso de vacíos o espacios en blanco sólo cadenas), entonces la expresión general s.strip() or 0 evalúa a 0.


O si usted sabe que la cadena siempre contiene caracteres de dígitos o sólo está vacía (""), entonces simplemente:

int(s or 0) 
Cuestiones relacionadas