2011-01-22 9 views
82

que tienen una línea del código siguiente (no culpa de las convenciones de nomenclatura, que no son míos):¿Cómo romper una línea de métodos encadenados en Python?

subkeyword = Session.query(
    Subkeyword.subkeyword_id, Subkeyword.subkeyword_word 
).filter_by(
    subkeyword_company_id=self.e_company_id 
).filter_by(
    subkeyword_word=subkeyword_word 
).filter_by(
    subkeyword_active=True 
).one() 

No me gusta cómo se ve (no demasiado legible), pero yo no' Tengo una mejor idea para limitar las líneas a 79 caracteres en esta situación. ¿Hay una mejor manera de romperlo (preferiblemente sin barras invertidas)?

Respuesta

171

Usted podría utilizar paréntesis adicional:

subkeyword = (
     Session.query(Subkeyword.subkeyword_id, Subkeyword.subkeyword_word) 
     .filter_by(subkeyword_company_id=self.e_company_id) 
     .filter_by(subkeyword_word=subkeyword_word) 
     .filter_by(subkeyword_active=True) 
     .one() 
    ) 
+0

También me gusta más. No agrega más código y sin barras diagonales inversas. –

+13

No estoy seguro de qué justifica la sangría adicional aquí; Creo que esta solución se lee igual de bien con las líneas colgantes sangradas una sola vez y la línea paren no. –

+0

En mi opinión, la sangría doble es útil aquí porque es visualmente distinta de un bloque sangrado normal. Cuando está rodeado por otro código, esto hace que sea más obvio que se trata de una sola línea envolvente. – sth

9

Simplemente almacene el resultado/objeto intermedio e invoque el siguiente método en él, p. Ej.

q = Session.query(Subkeyword.subkeyword_id, Subkeyword.subkeyword_word) 
q = q.filter_by(subkeyword_company_id=self.e_company_id) 
q = q.filter_by(subkeyword_word=subkeyword_word) 
q = q.filter_by(subkeyword_active=True) 
subkeyword = q.one() 
+4

Esto funciona bien para algo así como una consulta, pero como un patrón general, no estoy tan seguro. Por ejemplo, al encadenar en Beautiful Soup como 'team_members = soup.find (class _ = 'equipo de sección'). Find_all ('ul'). Find_all ('li')', el valor de retorno de cada '.find (.. .) 'llamada todavía no se ajusta al significado de' team_members'. –

4

Según Python Language Reference
Se puede utilizar una barra invertida.
O simplemente divídalo. Si un paréntesis no está emparejado, Python no lo tratará como una línea. Y bajo tal circunstancia, la sangría de las siguientes líneas no importa.

1

Usted parece usar SQLAlchemy, si bien es cierto, sqlalchemy.orm.query.Query.filter_by() método tiene varios argumentos de palabras clave, por lo que podría escribir como:

subkeyword = Session.query(Subkeyword.subkeyword_id, 
          Subkeyword.subkeyword_word) \ 
        .filter_by(subkeyword_company_id=self.e_company_id, 
           subkeyword_word=subkeyword_word, 
           subkeyword_active=True) \ 
        .one() 

Pero sería mejor:

subkeyword = Session.query(Subkeyword.subkeyword_id, 
          Subkeyword.subkeyword_word) 
subkeyword = subkeyword.filter_by(subkeyword_company_id=self.e_company_id, 
            subkeyword_word=subkeyword_word, 
            subkeyword_active=True) 
subkeuword = subkeyword.one() 
+0

+1 para SQLAlchemy filter_by() sugerencia. Es bueno para este ejemplo, pero a menudo uso filter() que acepta solo 1 condición. –

11

Mi elección personal Sería:

 
subkeyword = Session.query(
    Subkeyword.subkeyword_id, 
    Subkeyword.subkeyword_word, 
).filter_by(
    subkeyword_company_id=self.e_company_id, 
    subkeyword_word=subkeyword_word, 
    subkeyword_active=True, 
).one() 
+0

Acepto si hay varios parámetros que se pasan pero parece feo cuando los parámetros 0 o 1 son comunes. Por ejemplo: https://gist.github.com/andybak/b23b6ad9a68c7e1b794d –

+1

Sí, ese estilo tiene casos degenerados (como cualquier estilo). No rompería con todos los parens abiertos. Nada de esto me deja feliz, pero aquí hay algunos casos: https://gist.github.com/pkoch/8098c76614765750f769 – pkoch

38

Este es un caso donde una línea de continuación charac ter es preferible para abrir paréntesis. La necesidad de este estilo se hace más evidente que los nombres de métodos se hacen más largos y como métodos de empezar a tomar argumentos:

subkeyword = Session.query(Subkeyword.subkeyword_id, Subkeyword.subkeyword_word) \ 
        .filter_by(subkeyword_company_id=self.e_company_id)   \ 
        .filter_by(subkeyword_word=subkeyword_word)     \ 
        .filter_by(subkeyword_active=True)       \ 
        .one()              \ 

PEP 8 se tiene la intención de ser interpretados con una medida de sentido común y un ojo tanto para la práctica y la hermosa. Infrinja felizmente cualquier directriz PEP 8 que resulte en código feo o difícil de leer.

Dicho esto, si con frecuencia se encuentra en desacuerdo con PEP 8, puede ser una señal de que hay problemas de legibilidad que trascienden su elección de espacios en blanco :-)

+2

+1 en las barras diagonales inversas y alineando los filtros encadenados en este caso particular. Esta situación también se presenta en Django y es más fácil de leer de esta forma, pero en cualquier otra situación, siento que las frases entre paréntesis son superiores (no sufro el problema "¿hay espacio en blanco después de mi barra invertida?"). Dicho esto, se puede usar la frase entre paréntesis para lograr el mismo efecto, pero te pone en modo de lectura Lisp en el medio de la lectura de Python, lo cual me parece discordante. – zxq9

+7

No veo cómo esta solución es más capaz de sobrellevar "a medida que los nombres de los métodos se hacen más largos y los métodos comienzan a tomar argumentos" que el "ajuste en parens externos" o "line-break" después de cada paren abierto y antes de cada cierre "soluciones. De hecho, es peor al manejar eso, ya que (al menos como se muestra aquí) requiere una sangría mucho más profunda para cada línea colgante. –

+1

Demasiado sangría para las llamadas de filtro. Una pestaña o 4 espacios habrían sido suficientes aquí. También la alineación de '\' ... ¿Cuántos segundos mantuviste presionada esa tecla de espacio? En general, estoy en contra de todas las formas, que requieren que martillees esa tecla espacial como si no hubiera un mañana. – Zelphir

4

Es un poco de una solución diferente a proporcionado por otros, pero uno de mis favoritos, ya que a veces lleva a una metaprogramación ingeniosa.

base = [Subkeyword.subkeyword_id, Subkeyword_word] 
search = { 
    'subkeyword_company_id':self.e_company_id, 
    'subkeyword_word':subkeyword_word, 
    'subkeyword_active':True, 
    } 
subkeyword = Session.query(*base).filter_by(**search).one() 

Esta es una buena técnica para la creación de búsquedas. Revise una lista de condicionales para extraer de su formulario de consulta complejo (o deducciones basadas en cadenas sobre lo que el usuario está buscando), luego simplemente explote el diccionario en el filtro.

1

me gusta para sangrar los argumentos por los dos bloques, y la declaración de un bloque, como los siguientes:

for image_pathname in image_directory.iterdir(): 
    image = cv2.imread(str(image_pathname)) 
    input_image = np.resize(
      image, (height, width, 3) 
     ).transpose((2,0,1)).reshape(1, 3, height, width) 
    net.forward_all(data=input_image) 
    segmentation_index = net.blobs[ 
      'argmax' 
     ].data.squeeze().transpose(1,2,0).astype(np.uint8) 
    segmentation = np.empty(segmentation_index.shape, dtype=np.uint8) 
    cv2.LUT(segmentation_index, label_colours, segmentation) 
    prediction_pathname = prediction_directory/image_pathname.name 
    cv2.imwrite(str(prediction_pathname), segmentation) 
0

Sé que esto es un viejo tema, pero ¿qué pasa con:

subkeyword=(Session.query(Subkeyword.subkeyword_id, 
          Subkeyword.subkeyword_word) 
        .filter_by(subkeyword_company_id=self.e_company_id) 
        .filter_by(subkeyword_word=subkeyword_word) 
        .filter_by(subkeyword_active=True) 
        .one()) 

O

subkeyword=(Session.query(Subkeyword.subkeyword_id, 
          Subkeyword.subkeyword_word) 
        .filter_by(subkeyword_company_id=self.e_company_id) 
        .filter_by(subkeyword_word=subkeyword_word) 
        .filter_by(subkeyword_active=True) 
        .one() 
      ) 
Cuestiones relacionadas