2010-05-31 14 views
6

Acabo de pasar el último semestre en Uni learning python. Realmente lo disfruté y esperaba algunos consejos sobre cómo escribir más código "pitónico".Codificando el modo Python

Esta es la clase __init__ de una tarea reciente que hice. En el momento en que lo escribí, estaba tratando de descifrar cómo podía volver a escribir esto usando lambdas, o de una manera más ordenada y más eficiente, pero me quedé sin tiempo.

def __init__(self, dir): 

    def _read_files(_, dir, files): 

     for file in files: 

      if file == "classes.txt": 
       class_list = readtable(dir+"/"+file) 
       for item in class_list: 
        Enrol.class_info_dict[item[0]] = item[1:] 
        if item[1] in Enrol.classes_dict: 
         Enrol.classes_dict[item[1]].append(item[0]) 
        else: 
         Enrol.classes_dict[item[1]] = [item[0]] 

      elif file == "subjects.txt": 
       subject_list = readtable(dir+"/"+file) 
       for item in subject_list: 
        Enrol.subjects_dict[item[0]] = item[1] 

      elif file == "venues.txt": 
       venue_list = readtable(dir+"/"+file) 
       for item in venue_list: 
        Enrol.venues_dict[item[0]] = item[1:] 

      elif file.endswith('.roll'): 
       roll_list = readlines(dir+"/"+file) 
       file = os.path.splitext(file)[0] 
       Enrol.class_roll_dict[file] = roll_list 
       for item in roll_list: 
        if item in Enrol.enrolled_dict: 
         Enrol.enrolled_dict[item].append(file) 
        else: 
         Enrol.enrolled_dict[item] = [file] 


    try: 
     os.path.walk(dir, _read_files, None) 
    except: 
     print "There was a problem reading the directory" 

Como puede ver, es un poco voluminoso. Si alguien tiene el tiempo o la inclinación, realmente agradecería algunos consejos sobre algunas de las mejores prácticas de Python.

Gracias.

+0

Nota: esto era parte de un módulo llamado 'enrol', que contiene la clase' Enrol' para la cual este es el '__init__' –

+3

parece que tienes un compañero de clase: http://stackoverflow.com/questions/2943396/python -Necesitar algo de ayuda –

+1

Este aspecto s * notablemente * como http://stackoverflow.com/questions/2943396/python-need-some-help – Johnsyweb

Respuesta

5

par de cosas que pueden limpiar su código un poco:

utilizar setdefault del diccionario. Si falta la clave, la establece en el valor predeterminado que usted le proporciona, y luego la devuelve. De lo contrario, simplemente ignora el segundo parámetro y devuelve lo que estaba en el diccionario. Esto evita las torpes declaraciones if.

Enrol.venues_dict.setdefault(key, []).append(file) 

>>> x = {} 
>>> x.setdefault(99, []).append(5) 
>>> x.setdefault(99, []).append(6) 
>>> x 
{99: [5, 6]} 
>>> x.setdefault(100, []).append(1) 
>>> x 
{99: [5, 6], 100: [1]} 

La otra posibilidad es usar os.path.join para crear rutas de archivos. Esto es más seguro que solo hacer concatenación de cadenas.

os.path.join(dir, file) 

Aparte de eso, se ve bien en términos de estilo, IMO.

+0

Gracias, esa es una forma mucho más ordenada de implementar if/elif. –

2

Otro punto importante si se quiere usarte guión de tiempo (algunos dirían muy larga) es no utilizar funciones obsoletas en el nuevo código:

os.path.walk desaparecido en 3.x de pitón Ahora puede usar os.walk en su lugar. Sin embargo, os.walk es diferente a os.path.walk: no acepta una función de procesamiento en su firma. Por lo tanto, la refacturación de su código implicará un poco más que cambiar los nombres.

+0

gracias joaquin. Alguien más me lo señaló en otra publicación. Una vez más, no tuve tiempo de cambiarlo antes de enviarlo, pero lo echaré un vistazo ahora. –

3

Además de las sugerencias de orangeoctopus utilizar setdefault, puede refactorizar la if-else en un expedidor (la sustitución típico de grandes if-else y cambiar los estados):

# list of 2-tuples: (bool func(string filename), handler_function) 
handlers = [ 
    ((lambda fn: fn == "classes.txt"), HandleClasses), 
    ((lambda fn: fn == "subjects.txt"), HandleSubjects), 
    ((lambda fn: fn.endswith(".roll")), HandleRoll) 
] 

luego hacer

for filename in files: 
    for matcher, handler in handlers: 
    if matcher(filename): 
     handler(filename) 
     break 
+1

¡Guau, genial! Estaba buscando una gran alternativa de cambio y otra alternativa, y encontré algunas, pero nada tan limpio. Python sigue mejorando cada vez más;) ¡Gracias, Richard! –

+0

solo para aclarar, 'HandleClasses',' HandleSubjects', etc. son funciones con un parámetro 'filename'? Y aún los necesito definidos en la función '_read_files' para acceder a la var' dir' –

+1

Sí, correcto.Los necesitarías definidos en algún lugar donde se definan esos símbolos. También puedes hacerlo en '__init__' como' self.HandlerSubjects'. –

Cuestiones relacionadas