我們正在嘗試遵循PEP8格式化我們的Python代碼並保持每行低於80個字符的指導原則。格式化SQLAlchemy代碼
我們的SQLAlchemy行特別麻煩,有大量的鏈接方法和大量的複雜參數,邏輯和嵌套函數。
是否有任何特定的最佳實踐來格式化Python SQLAlchemy的約束PEP8?
我發現的最接近的答案是here,但我所處理的代碼遠遠更復雜。
我們正在嘗試遵循PEP8格式化我們的Python代碼並保持每行低於80個字符的指導原則。格式化SQLAlchemy代碼
我們的SQLAlchemy行特別麻煩,有大量的鏈接方法和大量的複雜參數,邏輯和嵌套函數。
是否有任何特定的最佳實踐來格式化Python SQLAlchemy的約束PEP8?
我發現的最接近的答案是here,但我所處理的代碼遠遠更復雜。
pep-8不鼓勵反斜槓,但對於SQLAlchemy代碼,我不禁想到它們是最可讀的,因爲您可以將每個生成函數保留在自己的行的開頭。如果括號內有很多參數,我會在個別行上分解它們。
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()
當然不要緊代碼是如何複雜的是它,壓痕模式可以爲任何代碼量進行下去,但是在Python我們要避免過多的嵌套。通常在使用Query時,會發生嵌套,因爲您正在組合許多子查詢。因此,絕對提前構建子查詢:
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)
我會歡迎其他意見反斜槓的事情。
是的,無論你做什麼,這些都會變得很討厭,所以如果你能把這些結構分成更短的行,那肯定是這樣。
當你不能的時候,你可以通過把整個RHS放在一個圓括號中去掉所有的反斜槓。然後,Python將正確地解析多行構造,而不用反斜槓,但也很難說這是否更好。在這樣的情況下,我認爲你只需要用你最好的判斷,抓住你的鼻子並投入。
pep8有關反斜槓的說明的機會是什麼(字面上,「這些應該優先使用反斜槓換行「)是唯一提及的)?如果他們不鼓勵,爲什麼Python甚至擁有它們? – zzzeek 2012-02-28 19:45:50
我是類似於zzzeek在他的回答中指出的反斜槓的用戶。 PEP8只是一個指導方針,當你違犯它時不要失眠!
不過,我也經常使用以下格式,在那裏我已經偷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()
反覆重新分配到q起初似乎有點討厭,但我已經完成了。性能影響實際上是零。這種方式的一大優勢是,您可以在尾部註釋和註釋行中混合使用,以記錄您的查詢(正如我對上面的無用添加所做的那樣)。用反斜槓鏈接線限制你在這裏。
格式的這種方式與邏輯觸發修改噸,嵌入式標量選擇等
作爲另一示例配製大量查詢時,特別乾淨,我有一個相當大(> 150線)CTE查詢我在SQLAlchemy中生成的混合邏輯,別名和標籤(這對生成的查詢的可讀性來說非常重要)混合了這兩種方法。它的一個嚴重降低(血肉模糊)版本開始像下面的東西:
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)...
在一般情況下,如果要確保新業務(如許多常見的SQL格式方案做)帶領你行了,它保持很可讀。不要害怕括號內的換行符。
這也帶來了額外的好處,它使得'pdb' a * lot *更容易調試!因爲每個過濾器都有自己的聲明! – exhuma 2014-02-24 10:20:47
來到這裏,希望有一個更好的解決方案,但我想我更喜歡括號環繞方式:
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()
)
這是很好的和明確的,並且避免了可怕的反斜槓。
pocoo團隊風格指南中很好的反斜槓用法http://www.pocoo.org/internal/styleguide/ – estin 2012-02-28 12:04:59