2011-01-22 19 views
82

Aşağıdaki kod satırını var (adlandırma için suçlamıyorum, onlar benim değil):Python'da zincirleme yöntemlerden nasıl ayrılır?

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() 

Ben (çok okunabilir değil) nasıl göründüğünü sevmiyorum ama ı don Bu durumda satırları 79 karakterle sınırlamak için daha iyi bir fikre sahip olmak. Onu kırmanın daha iyi bir yolu var mı (tercihen ters eğik çizgi olmadan)?

cevap

171

Ek parantez kullanabilirsiniz.
Ya da sadece kırın. Bir parantez eşleştirilmemişse, python bunu bir çizgi olarak ele almayacaktır. Ve böyle bir durumda, aşağıdaki satırların girintisi önemli değildir.

Bunun gerçek ise, böyle yazabilmesi için sqlalchemy.orm.query.Query.filter_by() yöntem, birden fazla anahtar kelime argümanları alır SQLAlchemy kullanarak görünüyor
+0

Ayrıca en çok beğendim. Daha fazla kod eklemez ve ters eğik çizgi içermez. –

+13

Burada ekstra girintiyi haklı çıkardığından emin değil; Bence bu çözüm, sadece bir kez girilen askı çizgileri ve takip eden paren hiç de iyi değil. –

+0

Benim görüşüme göre, burada çift girinti normal bir girintili bloktan görsel olarak farklı olduğu için yararlıdır. Diğer kodlarla çevrildiğinde, bunun sarılmış tek bir satır olduğu daha açık hale gelir. – sth

9

Ara sonucu/nesneyi saklayın ve bir sonraki yöntemi , örn. Bir ters eğik çizgi kullanabilirsiniz Python Language Reference
göre

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() 
    ) 
+4

Bu, bir sorgu gibi bir şey için iyi çalışır, ancak genel bir desen olarak, emin değilim. Örneğin, Güzel Çorbada zincirleme yaparken 'team_members = soup.find (class _ =' bölüm ekibi '). Find_all (' ul '). Find_all (' li ') ', herbirinden dönüş değeri .find (.. .) 'çağrı henüz 'team_members' anlamına uymuyor. –

4

:

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() 
1

:

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() 

Ama daha iyi olurdu:

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. Bu örnek için iyidir, ancak çoğunlukla yalnızca 1 koşulu kabul eden filter() kullanırım. –

11

Benim kişisel tercihi şöyle olurdu:

 
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

Geçtiğimiz birkaç parametre olup olmadığını kabul ediyorum ancak 0 veya 1 parametresi yaygın olduğunda çirkin görünüyor. Örneğin: https://gist.github.com/andybak/b23b6ad9a68c7e1b794d –

+1

Evet, bu stil dejenere vakalar (herhangi bir stil gibi) var. Tüm açık parensleri kırmayacağım. Bunların hiçbiri beni mutlu etmiyor, ama burada bazı durumlar var: https://gist.github.com/pkoch/8098c76614765750f769 – pkoch

38

Bu, satır devam karakterinin bulunduğu bir durumdur. Parantez açmak için ter tercih edilir. sağduyu bir ölçüsü ve pratik hem de bir göz ile yorumlanmalıdır niyetinde olduğu

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: yöntemler alarak argümanlar başlar başlamaz yöntem adları daha uzun olsun ve bu tarz ihtiyacı daha belirgin hale gelir güzel. Çirkin veya okunması zor bir kodla sonuçlanan herhangi bir PEP 8 rehberini mutlu bir şekilde ihlal edin. Sık sık PEP 8 ile oran bulursanız

söyleniyor, bu farklı bir çözümün biraz

+2

+1 ters eğik çizgi işaretleri ve bu özel durumda zincirleme filtreleri hizalama. Bu durum Django'da da ortaya çıkıyor ve bu şekilde en çok okunabiliyor - ama _any_'de başka bir durumda parantezleşmiş ifadeler üstündeymiş gibi hissediyorum (“ters eğik çizgiden sonra boşluk var mı?” Sorunu). Yani, cümlenin parantezleştirilmesi, aynı etkiyi elde etmek için kullanılabilir - ancak, Python okuma ortasında, okumaya başladığım Lisp okuma moduna geçirir. – zxq9

+7

Bu çözümün, "yöntem adları uzadıkça ve yöntemler argüman almaya başladıkça," dış parenste sarma "veya" açık parenlerden sonra ve her yakın parenten önce satır sonu "dan daha iyi başa çıkabileceğini göremiyorum "çözümler. Aslında bunu ele almada daha da kötüdür, çünkü (en azından burada gösterildiği gibi) her asılı hat için daha derin bir girinti gerektirir. –

+1

Filtre çağrıları için çok fazla girinti. Burada bir sekme veya 4 boşluk yeterli olurdu. Ayrıca '\ '...' nin hizalanması Bu boşluk tuşunu kaç saniye basılı tuttunuz? Genelde, yarın yokmuş gibi boşluk tuşunu kullanmanı gerektiren tüm yollara karşıyım. – Zelphir

4

:-) boşluk seçiminiz aşmak okunabilirliği sorunlar olduğunu bir işareti olabilir Başkaları tarafından sağlanan ama benim favorim bazen elli metaprogramming yol açar beri.

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() 

Bu, arama yapıları için güzel bir tekniktir. Karmaşık sorgu formunuzdan (veya kullanıcının aradığı şeyle ilgili dize dayalı kesintilerden) benimki için koşullu bir listeyi gözden geçirin, sonra sözlüğü yalnızca filtreye çıkarın.

1

iki bloktan tarafından argümanları girinti ister ve bir blok tarafından açıklamada, bu gibi:

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

Ben bu eski bir konu ama ne ile ilgili olduğunu biliyorum:

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()) 

Ya

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() 
      ) 
İlgili konular