2012-02-28 13 views
14

हम अपने पायथन कोड को स्वरूपित करने और प्रति पंक्ति 80 वर्णों के नीचे रहने के लिए PEP8 दिशानिर्देशों का पालन करने का प्रयास कर रहे हैं।स्वरूपण SQLAlchemy कोड

हमारी एसक्लाक्लेमी लाइनें विशेष रूप से परेशानी होती हैं, जिनमें बहुत सी जंजीर विधियां और जटिल पैरामीटर, तर्क और नेस्टेड फ़ंक्शंस शामिल हैं।

क्या पीईपी 8 की बाधाओं के साथ पाइथन स्क्लाक्लेमी को स्वरूपित करने के लिए कोई विशेष सर्वोत्तम अभ्यास है?

मुझे मिला सबसे नज़दीकी उत्तर here है, लेकिन जिस कोड से मैं निपट रहा हूं वह बहुत जटिल है।

उत्तर

7

पेप -8 बैकस्लाश को हतोत्साहित करता है लेकिन स्क्लाक्लेमी कोड के लिए मैं मदद नहीं कर सकता लेकिन लगता है कि वे सबसे अधिक पठनीय हैं, क्योंकि आप प्रत्येक जेनरेटिव फ़ंक्शन को अपनी लाइन की शुरुआत में रख सकते हैं। यदि ब्रांड्स के अंदर कई तर्क हैं तो मैं उन्हें व्यक्तिगत लाइनों पर भी तोड़ दूंगा।

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() 
पाठ्यक्रम कोई फर्क नहीं पड़ता कैसे जटिल कोड है की

यह, खरोज पैटर्न कोड के किसी भी राशि के लिए आगे बढ़ाया जा सकता है, पायथन में लेकिन हम अत्यधिक घोंसले से बचना चाहते हैं। आम तौर पर क्वेरी के साथ घोंसला होता है क्योंकि आप कई सबक्वायरीज़ एक साथ लिख रहे हैं। तो निश्चित रूप से समय से पहले subqueries का निर्माण:

subq = Session.query(
       Bat.id, 
       func.foo(Bat.x, Bat.y).label('foo') 
       ).\ 
       filter(Bat.id==Bar.name).\ 
       correlate(Bar).\ 
       subquery() 

subq2 = Session.query(Foo.id, Foo.bar).\ 
       filter_by(flag>5).\ 
       subquery() 

result = Session.query(
        subq.c.id, 
        subq.c.foo, 
        subq2.c.bar 
       ).\ 
       join(subq2, 
        and_(
         subq.c.id > subq2.c.foo, 
         subq.bar == subq2.id 
        ) 
       ).\ 
       order_by(subq.c.id, subq2.c.bar) 

मैं बैकस्लैश चीज़ पर अन्य राय का स्वागत करता हूं।

+2

पॉको टीम शैली मार्गदर्शिका में अच्छा बैकस्लाश उपयोग http://www.pocoo.org/internal/styleguide/ – estin

1

हाँ, ये कोई फर्क नहीं पड़ता कि आप क्या करते हैं, इस हद तक कि आप इन संरचनाओं को छोटी लाइनों में विभाजित कर सकते हैं, निश्चित रूप से ऐसा करते हैं।

जब आप नहीं कर सकते हैं, तो आप शायद संपूर्ण आरएचएस को एक कोष्ठक में डालकर उन सभी बैकस्लैश से छुटकारा पा सकते हैं। पाइथन फिर बैकस्लेश के बिना मल्टीलाइन संरचनाओं को सही तरीके से पार्स करेगा, लेकिन यह भी मुश्किल है कि यह बेहतर है या नहीं। इन मामलों में, मुझे लगता है कि आपको बस अपने सबसे अच्छे फैसले का उपयोग करना होगा, अपनी नाक पकड़ना होगा और डुबकी डालना होगा।

+1

बैकस्लाश के बारे में स्पष्ट रूप से पेप 8 की स्पष्टता की संभावना क्या है (शाब्दिक रूप से, "इन्हें बैकस्लैश का उपयोग करने के लिए प्राथमिकता में उपयोग किया जाना चाहिए लाइन निरंतरता के लिए। "केवल एकमात्र उल्लेख है)? अगर वे निराश हो जाते हैं, तो पाइथन भी उन्हें क्यों लेता है? – zzzeek

2

मैं बैकस्लैश का एक लगातार उपयोगकर्ता हूं जो उसके जवाब में ज़ेज़ेक ने संकेत दिया था। पीईपी 8 सिर्फ एक दिशानिर्देश है, जब आप इसका उल्लंघन करते हैं तो उस पर नींद न खोएं!

हालांकि, मैं भी अक्सर नीचे स्वरूपण, जहां मैं zzzeek का पहला उदाहरण चोरी कर लिया है के प्रकार का उपयोग करें, हल्का यह बदलाव किया है, और पुन: स्वरूपित:

q = Session.query(
    Subkeyword.subkeyword_id, 
    Subkeyword.subkeyword_word, 
) 
q = q.filter_by(subkeyword_company_id=self.e_company_id) # first filter 
q = q.filter_by(subkeyword_word=subkeyword_word) # 2nd filter 
q = q.filter_by(subkeyword_active=True) 

if filter_by_foo: 
    q = q.filter(Subkeyword.foo == True) 

# Run the query (I usually wrap in a try block)... 
subkeyword = q.one() 

क्ष को दोहराया रीअसाइनमेंट पहली बार में एक तरह से बुरा लगता है , लेकिन मैं इसे खत्म कर लिया है। प्रदर्शन प्रभाव प्रभावी रूप से शून्य है। इस तरह से एक बड़ा फायदा यह है कि आप अपने प्रश्नों को दस्तावेज करने के लिए पिछली टिप्पणियों और टिप्पणी पंक्तियों में मिश्रण कर सकते हैं (जैसा कि मैंने उपरोक्त बेकार जोड़ों के साथ किया है)। बैकस्लाश के साथ चेनिंग लाइनें आपको यहां सीमित करती हैं।

स्वरूपण का इस तरह से जब आदि

तर्क ट्रिगर संशोधनों के टन, एम्बेडेड अदिश चयन, एक और उदाहरण के रूप में के साथ बड़े पैमाने पर प्रश्नों तैयार विशेष रूप से साफ है, मैं एक काफी बड़े (> 150 लाइनों) CTE क्वेरी मेरे पास है मैं एसक्लाक्लेमी में उत्पन्न कर रहा हूं जिसमें बहुत सारे मिश्रित तर्क, एलियासिंग और लेबलिंग (जो उत्पन्न क्वेरी की पठनीयता के लिए आवश्यक है) है जो दोनों विधियों को मिश्रित करती है।,

cte_init = session.\ 
    query(
     child1.foo.label("child1_foo"), 
     sa.literal(1).label("indent"), # can comment on non-slashed lines 
     child2.bar.label("child2bar"), 
     #comments between non-slashed lines ok, too 
     sa.func.MAX(toplevel.baz).label("max_baz"), 
    ).\ 
    select_from(top_level).\ 
    join(child1, 
     child1.id == toplevel.fk_child1_id).\ 
    join(child2. 
     child2.id == toplevel.fk_child2.id).\ 
    filter(top_level.name == "bogus").\ 
    cte(name = "cte", recursive = True) 

if(use_filter_x): 
    cte_init = cte_init.filter_by(x = "whatever") 

# etc (no, the above doesn't make any sense)... 

सामान्य तौर पर अगर आप अपने लाइनों नई परिचालन (कई आम एसक्यूएल स्वरूपण योजनाओं की तरह करते हैं) के साथ बंद का नेतृत्व करने के लिए सुनिश्चित करें, यह रहता है: यह एक गंभीर रूप से कम हो (और घायल) संस्करण नीचे की तरह कुछ शुरू होता है काफी पठनीय ब्रैकेट के भीतर न्यूलाइन से डरो मत, या तो।

+1

इसमें अतिरिक्त लाभ भी है जो यह 'pdb' a * lot * के साथ डीबगिंग करता है! प्रत्येक फिल्टर अपने स्वयं के बयान पर बन गया है! – exhuma

24

यहाँ आया एक बेहतर समाधान के लिए उम्मीद है, लेकिन मुझे लगता है कि मैं कोष्ठकों रैपिंग शैली पसंद करते हैं:

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

यह अच्छा और साफ है, और खतरनाक बैकस्लैश बचा जाता है।