




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
Python編碼規(guī)范匯編前言:為了讓不同編碼習(xí)慣的開發(fā)者更好的協(xié)作配合,并且形成良好的基礎(chǔ)編碼規(guī)范與風(fēng)格,我們以PEP8為基礎(chǔ),修改了陳舊的規(guī)則,豐富了示例,并整理了工作中常見的不規(guī)范操作,最終形成此Python編碼規(guī)范與風(fēng)格。一、編碼風(fēng)格1.1縮進(jìn)1.2每行最大長度1.3空白符1.4操作符1.5括號1.6空行1.7源文件編碼1.8Shebang1.9模塊引用(import)1.10模塊中的魔術(shù)變量(dunders)1.11注釋1.12文檔字符串1.13類型提示1.14字符串1.15文件和sockets1.16訪問控制1.17Main1.18命名二、編碼規(guī)范2.1三目運(yùn)算符2.2None條件的判斷2.3lambda匿名函數(shù)2.4異常2.5條件表達(dá)式2.6True/False布爾運(yùn)算2.7列表推導(dǎo)式2.8函數(shù)2.9變量工具與配置flake8pylintblackEditorConfig注意事項(xiàng)本規(guī)范適用于所有使用Python語言作為開發(fā)語言的軟件產(chǎn)品。由于Python2在2020年停止維護(hù),建議新增的項(xiàng)目使用Python3.6+,可以使用到更多的高級特性。如果項(xiàng)目有兼容性需求需要支持老版本Python的,那么不涉及的特性可以忽略。本規(guī)范的示例采用符合Python3.6+的語法。必須(Mandatory):用戶必須采用;推薦(Preferable):用戶理應(yīng)采用,但如有特殊情況,可以不采用;可選(Optional):用戶可參考,自行決定是否采用;未明確指明的則默認(rèn)為
必須(Mandatory)。一、編碼風(fēng)格規(guī)范地代碼布局有助于幫助開發(fā)者更容易地理解業(yè)務(wù)邏輯。1.1縮進(jìn)1.1.1
【必須】
對于每級縮進(jìn),統(tǒng)一要求使用4個空格,而非tab鍵。pylint:bad-indentation.1.1.2
【必須】
續(xù)行,要求使用括號等定限界符,并且需要垂直對齊。正確示范#
與定界(括號)符對齊
foo
=
long_function_name(var_one,
var_two,
var_three,
var_four)
#
換行并增加4個額外的空格(一級縮進(jìn))
def
long_function_name(
var_one,
var_two,
var_three,
var_four):
print(var_one)
#
懸掛需要增加一級縮進(jìn)
foo
=
long_function_name(
var_one,
var_two,
var_three,
var_four)錯誤示范
#
當(dāng)不使用垂直對齊時,第一行不允許加參數(shù)
foo
=
long_function_name(var_one,
var_two,
var_three,
var_four)
#
下面這種情況,需要增加額外的縮進(jìn),否則無法區(qū)分代碼所在的縮進(jìn)級別
def
long_function_name(
var_one,
var_two,
var_three,
var_four):
print(var_one)1.1.3
【推薦】
如果包含定界符(括號,中括號,大括號)的表達(dá)式跨越多行,那么定界符的擴(kuò)回符,可以放置與最后一行的非空字符對齊或者與構(gòu)造多行的開始第一個字符對齊。正確示范#
與最后一行的非空字符對齊
my_list
=
[
1,
2,
3,
4,
5,
6,
]
result
=
some_function_that_takes_arguments(
'a',
'b',
'c',
'd',
'e',
'f',
)
#
或者與開始構(gòu)造多行的第一個字符對齊
my_list
=
[
1,
2,
3,
4,
5,
6,
]
result
=
some_function_that_takes_arguments(
'a',
'b',
'c',
'd',
'e',
'f',
)1.1.4
【推薦】
對于會經(jīng)常改動的函數(shù)參數(shù)、列表、字典定義,建議每行一個元素,并且每行增加一個
,
。正確示范yes
=
('y',
'Y',
'yes',
'TRUE',
'True',
'true',
'On',
'on',
'1')
#
基本不再改變
kwlist
=
[
'False',
'None',
'True',
'and',
'as',
'assert',
...
'yield',
#
最后一個元素也增加一個逗號
,方便以后diff不顯示此行
]
person
=
{
'name':
'bob',
'age':
12,
#
可能經(jīng)常增加字段
}錯誤示范#
關(guān)鍵字會不斷增加,每個元素都換行
kwlist
=
['False',
'None',
'True',
'and',
'as',
'assert',
'async',
...
]
person
=
{'name':
'bob',
'age':
12}1.1.5
【可選】
對于if判斷,一般來說盡量不要放置過多的判斷條件。換行時增加4個額外的空格。pycodestyle:E129visuallyindentedlinewithsameindentasnextlogicalline.備注:PEP8沒有明確規(guī)定,以下幾種都是允許的。建議使用前面2種方法,后2種會與已有的開源工具沖突。正確示范#
更推薦:在續(xù)行中,增加額外的縮進(jìn)級別。允許and操作符在前
if
(this_is_one_thing
and
that_is_another_thing):
do_something()
#
更推薦:在續(xù)行中,增加額外的縮進(jìn)級別
if
(this_is_one_thing
and
that_is_another_thing):
do_something()
#
允許:與定界符(括號)對齊,不需要額外的縮進(jìn)
if
(this_is_one_thing
and
that_is_another_thing):
do_something()
#
允許:增加注釋,編輯器會提示語法高亮,有助于區(qū)分
if
(this_is_one_thing
and
that_is_another_thing):
#
Since
both
conditions
are
true,
we
can
frobnicate.
do_something()1.2每行最大長度1.2.1
【必須】
每行最多不超過
120
個字符。每行代碼最大長度限制的根本原因是過長的行會導(dǎo)致閱讀障礙,使得縮進(jìn)失效。pylint:line-too-long.除了以下兩種情況例外:導(dǎo)入模塊語句。注釋中包含的URL。如果需要一個長的字符串,可以用括號實(shí)現(xiàn)隱形連接。正確示范x
=
('This
will
build
a
very
long
long
'
'long
long
long
long
long
long
string')1.3空白符1.3.1
【必須】
在表達(dá)式的賦值符號、操作符左右至少有一個空格。正確示范x
=
y
+
1錯誤示范x=y+1
x
=
y+11.3.2
【必須】
禁止行尾空白。pylint:trailing-whitespace.行尾空白雖然不會造成功能性異常,但是這些空白字符會被源碼管理系統(tǒng)標(biāo)記出來顯示為差異,對開發(fā)人員造成困惱。正確示范#
YES:
尾部沒有空白符號
+
para
=
{}
+
para
=
{}
#
comment錯誤示范#
No:
結(jié)尾存在多余空白符號
-
para
=
{}?????
-
para
=
{}
#
comment??????1.4操作符1.4.1
【推薦】
Python沒有三目操作符,對于二目操作符來說,操作符允許在換行符之后出現(xiàn)。備注:pycodestyle工具與此條目相反,PEP8推薦操作符在這之前,更具備可讀性。PEP8:ShouldaLineBreakBeforeorAfteraBinaryOperator?。屏蔽pycodestyle:W503linebreakbeforebinaryoperator正確示范#
YES:
易于將運(yùn)算符與操作數(shù)匹配,可讀性高
income
=
(gross_wages
+
taxable_interest
+
(dividends
-
qualified_dividends)
-
ira_deduction
-
student_loan_interest)錯誤示范#
No:
運(yùn)算符的位置遠(yuǎn)離其操作數(shù)
income
=
(gross_wages
+
taxable_interest
+
(dividends
-
qualified_dividends)
-
ira_deduction
-
student_loan_interest)1.5括號1.5.1
【必須】
tuple元組不允許逗號結(jié)尾,顯式增加括號規(guī)避。即使一個元素也加上括號。pylint:trailing-comma-tuple.行尾的逗號可能導(dǎo)致本來要定義一個簡單變量,結(jié)果變成tuple變量。正確示范trailingcomma
=
(['f'],)
return
(1,)錯誤示范trailingcomma
=
['f'],
#
tuple
return
1,1.6空行1.6.1
【必須】
模塊中的一級函數(shù)和類定義之間,需要空兩行。pycodestyle:E302expected2blanklines.1.6.2
【必須】
類中函數(shù)定義之間,空一行。pycodestyle:E302expected1blankline.1.6.3
【必須】
源文件須使用且僅使用
一個換行符
作為結(jié)尾。pylint:missing-final-newline,
trailing-newlines.1.6.4
【必須】
通常每個語句應(yīng)該獨(dú)占一行。pylint:multiple-statements.如果測試結(jié)果與測試語句在一行放得下,你也可以將它們放在同一行。如果是
if
語句,只有在沒有
else
時才能這樣做。特別地,絕不要對
try/except
這樣做,因?yàn)?/p>
try
和
except
不能放在同一行。正確示范if
foo:
bar(foo)
else:
baz(foo)
try:
bar(foo)
except
ValueError:
baz(foo)錯誤示范if
foo:
bar(foo)
else:
baz(foo)
try:
bar(foo)
except
ValueError:
baz(foo)
try:
bar(foo)
except
ValueError:
baz(foo)1.6.5
【推薦】
可以在代碼段中的空一行來區(qū)分不同業(yè)務(wù)邏輯塊。"""This
is
the
example
module.
This
module
does
stuff.
"""
import
os
def
foo():
pass
class
MyClass():
def
__init__(self):
pass
def
foo(self):
pass
class
AnotherClass(object):
"""Another
class.
This
is
some
comments
for
another
class
"""
def
__init__(self,
a,
b):
if
a
>
b:
self._min
=
b
self._max
=
a
else:
self._min
=
a
self._max
=
b
self._gap
=
self._max
=
self._min
def
foo(self):
pass1.7源文件編碼1.7.1
【必須】
源文件編碼需統(tǒng)一使用
UTF-8
編碼,以下內(nèi)容需要增加到每一個python文件的頭部。#
-*-
coding:
utf-8
-*-1.7.2
【必須】
**避免不同操作系統(tǒng)對文件換行處理的方式不同,一律使用
LF**。pylint:mixed-line-endings,
unexpected-line-ending-format.1.8Shebang1.8.1
【必須】
程序的main文件應(yīng)該以
#!/usr/bin/envpython2
或者
#!/usr/bin/envpython3
開始,可以同時支持Python2、Python3的#!/usr/bin/envpython。非程序入口的文件不應(yīng)該出現(xiàn)Shebang。正確示范#!/usr/bin/env
python3
#
-*-
coding:
utf-8
-*-
#1.9模塊引用(import)1.9.1
【必須】
每個導(dǎo)入應(yīng)該獨(dú)占一行。pylint:multiple-imports.正確示范import
os
import
sys錯誤示范import
os,
sys1.9.2
【必須】
導(dǎo)入總應(yīng)該放在文件頂部,位于模塊注釋和文檔字符串之后,模塊全局變量和常量之前。pylint:wrong-import-order.導(dǎo)入應(yīng)該按照從最通用到最不通用的順序分組,每個分組之間,需要空一行:標(biāo)準(zhǔn)庫導(dǎo)入第三方庫導(dǎo)入本地導(dǎo)入每種分組中,建議每個模塊的完整包路徑按
字典序
排序,并忽略大小寫。正確示范import
foo
from
foo
import
bar
from
foo.bar
import
baz
from
foo.bar
import
Quux
from
Foob
import
ar1.9.3
【必須】
避免使用
from<module>import*,因?yàn)榭赡軙斐擅臻g的污染。pylint:wildcard-import.1.9.4
【必須】
禁止導(dǎo)入了模塊卻不使用它。pylint:unused-import.正確示范import
os
#
used
dir_path
=
os.path.abspath('.')錯誤示范import
os
#
unused
!
#
dir_path
=
os.path.abspath('.')1.10模塊中的魔術(shù)變量(dunders)1.10.1
【必須】
對于兩個
_
開頭和兩個
_
結(jié)尾的變量,如
__all__,__author__,__version__等,應(yīng)該放在模塊文檔之后,其他模塊導(dǎo)入之前(__future__
除外)。1.10.2
【必須】
Python要求
future
導(dǎo)入必須出現(xiàn)在其他模塊導(dǎo)入之前。pylint:misplaced-future.正確示范#
-*-
coding:
utf-8
-*-
#
#
Copyright
@
2020
T
"""This
is
the
example
module.
This
module
does
stuff.
"""
from
__future__
import
barry_as_FLUFL
__all__
=
['a',
'b',
'c']
__version__
=
'0.1'
__author__
=
'Cardinal
Biggles'
import
os
import
sys1.11注釋有效的注釋有助于幫助開發(fā)者更快地理解代碼,模塊,函數(shù),方法,以及行內(nèi)注釋的都有各自的風(fēng)格。1.11.1
【必須】
所有#開頭的注釋,必須與所在的代碼塊同級,并置放在代碼之上。pycodestyle:E262inlinecommentshouldstartwith'#'.1.11.2
【必須】
注釋的每一行都應(yīng)該以#和一個空格開頭。pycodestyle:E266toomanyleading'#'forblockcomment,
E262inlinecommentshouldstartwith'#'.1.11.3
【必須】
行內(nèi)注釋#與代碼離開至少2個空格。pycodestyle:E261atleasttwospacesbeforeinlinecomment.1.11.4
【必須】
塊注釋:對于復(fù)雜的操作,可以在代碼之前寫若干行注釋,對簡單的代碼,可以放在行內(nèi)。與代碼離開至少2個空格。正確示范#
this
is
a
very
complex
operation,
please
#
read
this
carefully
if
i
&
(i-1)
==
0:
#
do
my
job
...
#
單行注釋,為可讀性,至少離開代碼2個空格
x
=
x
+
1
#
Compensate
for
border1.11.5
【必須】
TODO注釋需要加上名字。TODO注釋應(yīng)該在所有開頭處包含
TODO
字符串,緊跟著是用括號括起來的你的名字,email地址或其它標(biāo)識符,然后是一個可選的冒號。接著必須有一行注釋,解釋要做什么。主要目的是為了有一個統(tǒng)一的TODO格式,這樣添加注釋的人就可以搜索到(并可以按需提供更多細(xì)節(jié))。寫了TODO注釋并不保證寫的人會親自解決問題。當(dāng)你寫了一個TODO,請注上你的名字。為臨時代碼使用TODO注釋,它是一種短期解決方案。常見的IDE在提交代碼時,會檢查變更中包含了TODO并提醒開發(fā)者,防止提交是忘記還有未完成的代碼。如果TODO是將來做某事的形式,那么請確保包含一個指定的日期或者一個特定的事件(條件)。相同地,也可以留下
FIXME,
NOTES
注釋。正確示范#
TODO(zhangsan):
Change
this
to
use
relations.
#
FIXME(zhangsan@):
Please
fix
me
here.
#
NOTES(zhangsan):
This
is
some
notes.1.12文檔字符串Docstring文檔字符串提供了將文檔與Python模塊,函數(shù),類和方法相關(guān)聯(lián)的便捷方法。def
foobar():
"""Return
a
foobang
Optional
plotz
says
to
frobnicate
the
bizbaz
first.
"""PEP257全面描述了文檔字符串的風(fēng)格。1.12.1
【推薦】
需對外發(fā)布的public模塊,函數(shù),類,方法等需要包含文檔字符串。內(nèi)部使用的方法,函數(shù)等,要求使用簡單的注釋描述功能。pylint:missing-module-docstring,
missing-class-docstring,
missing-function-docstring.一個函數(shù)或方法,如果可以直接被其他開發(fā)者使用,需要提供文檔明確其含義,需要指出輸入,輸出,以及異常內(nèi)容。1.12.2
【必須】
第一行應(yīng)為文檔名,空一行后,輸入文檔描述。1.12.3
【推薦】
在使用文檔字符串時,推薦使用
reStructuredText
風(fēng)格類型。正確示范def
fetch_bigtable_rows(big_table,
keys,
other_silly_variable=None):
"""Fetches
rows
from
a
Bigtable.
Retrieves
rows
pertaining
to
the
given
keys
from
the
Table
instance
represented
by
big_table.
Silly
things
may
happen
if
other_silly_variable
is
not
None.
:param
big_table:
An
open
Bigtable
Table
instance.
:param
keys:
A
sequence
of
strings
representing
the
key
of
each
table
row
to
fetch.
:param
other_silly_variable:
Another
optional
variable,
that
has
a
much
longer
name
than
the
other
args,
and
which
does
nothing.
:return:
A
dict
mapping
keys
to
the
corresponding
table
row
data
fetched.
Each
row
is
represented
as
a
tuple
of
strings.
For
example:
{'Serak':
('Rigel
VII',
'Preparer'),
'Zim':
('Irk',
'Invader'),
'Lrrr':
('Omicron
Persei
8',
'Emperor')}
If
a
key
from
the
keys
argument
is
missing
from
the
dictionary,
then
that
row
was
not
found
in
the
table.
:raises
ValueError:
if
`keys`
is
empty.
:raises
IOError:
An
error
occurred
accessing
the
bigtable.Table
object.
"""
pass1.12.4
【推薦】
類應(yīng)該在其定義下有一個用于描述該類的文檔字符串。如果類有公共屬性(Attributes),那么文檔中應(yīng)該有一個屬性(Attributes)段,并且應(yīng)該遵守和函數(shù)參數(shù)相同的格式。正確示范class
SampleClass(object):
"""Summary
of
class
here.
Longer
class
information
Longer
class
information
:ivar
likes_spam:
A
boolean
indicating
if
we
like
SPAM
or
not.
:ivar
eggs:
An
integer
count
of
the
eggs
we
have
laid.
"""
def
__init__(self,
likes_spam=False):
"""Inits
SampleClass
with
blah."""
self.likes_spam
=
likes_spam
self.eggs
=
0
def
public_method(self):
"""Performs
operation
blah."""1.13類型提示Python是動態(tài)語言,在運(yùn)行時無需指定變量類型。雖然運(yùn)行時不會執(zhí)行函數(shù)與變量類型注解,但類型提示有助于閱讀代碼、重構(gòu)、靜態(tài)代碼檢查與IDE的語法提示。推薦在項(xiàng)目中使用該特性。更多使用可以參考類型標(biāo)注支持。類型提示示例代碼from
typing
import
List
class
Container(object):
def
__init__(self)
->
None:
self.elements:
List[int]
=
[]
def
append(self,
element:
int)
->
None:
self.elements.append(element)
def
greeting(name:
str)
->
str:
return
'Hello
'
+
name
#
變量定義
lang:
str
=
'zh'
success_code:
int
=
01.13.1
【必須】
模塊級變量,類和實(shí)例變量以及局部變量的注釋應(yīng)在冒號后面有一個空格。pycodestyle:E231missingwhitespaceafter':'.1.13.2
【必須】
冒號前不應(yīng)有空格。1.13.3
【必須】
如果有賦值符,則等號在兩邊應(yīng)恰好有一個空格。pycodestyle:E225missingwhitespacearoundoperator.正確示范code:
int
=
10
class
Point(object):
coords:
Tuple[int,
int]
=
(0,
0)
label:
str
=
'<unknown>'
def
broadcast(servers:
Sequence[Server],
message:
str
=
'spaces
around
equality
sign')
->
None:
pass錯誤示范code:int
#
No
space
after
colon
code
:
int
#
Space
before
colon
class
Test(object):
result:
int=0
#
No
spaces
around
equality
sign1.13.4
【推薦】
當(dāng)使用類型提示出現(xiàn)循環(huán)引用時,可以在導(dǎo)入的頭部使用
iftyping.TYPE_CHECKING
,且對類型注解使用雙引號或單引號進(jìn)行修飾。正確示范import
typing
if
typing.TYPE_CHECKING:
#
運(yùn)行時不導(dǎo)入
#
For
type
annotation
from
typing
import
Any,
Dict,
List,
Sequence
#
NOQA
from
sphinx.application
import
Sphinx
#
NOQA
class
Parser(docutils.parsers.Parser):
def
set_application(self,
app:
"Sphinx")
->
None:
#
同時采用引號
pass1.14字符串1.14.1
【推薦】
即使參數(shù)都是字符串,也要使用%操作符或者格式化方法格式化字符串。不過也不能一概而論,你需要在+和%之間權(quán)衡。正確示范#
更推薦
x
=
f'name:
{name};
score:
{n}'
#
Python3.6+
以上支持
x
=
'name:
{name};
score:
{n}'.format(name=name,
n=n)
x
=
'name:
{name};
score:
{n}'.format(**{"name":
name,
"n":
n})
x
=
'name:
%(name)s;
score:
%(n)d'
%
{"name":
name,
"n":
n}
#
可接受
x
=
'%s,
%s!'
%
(imperative,
expletive)
x
=
'{},
{}!'.format(imperative,
expletive)
x
=
'name:
%s;
score:
%d'
%
(name,
n)
x
=
'name:
{};
score:
{}'.format(name,
n)錯誤示范x
=
'%s%s'
%
(a,
b)
#
use
+
in
this
case
x
=
'{}{}'.format(a,
b)
#
use
+
in
this
case
x
=
imperative
+
',
'
+
expletive
+
'!'
x
=
'name:
'
+
name
+
';
score:
'
+
str(n)1.14.2
【推薦】
避免在循環(huán)中用
+
和
+=
操作符來累加字符串。由于字符串是不可變的,這樣做會創(chuàng)建不必要的臨時對象,并且導(dǎo)致二次方而不是線性的運(yùn)行時間。作為替代方案,你可以將每個子串加入列表,然后在循環(huán)結(jié)束后用
.join
連接列表。(也可以將每個子串寫入一個io.StringIO緩存中。)pylint:consider-using-join.正確示范items
=
['<table>']
for
last_name,
first_name
in
employee_list:
items.append('<tr><td>%s,
%s</td></tr>'
%
(last_name,
first_name))
items.append('</table>')
employee_table
=
''.join(items)錯誤示范employee_table
=
'<table>'
for
last_name,
first_name
in
employee_list:
employee_table
+=
'<tr><td>%s,
%s</td></tr>'
%
(last_name,
first_name)
employee_table
+=
'</table>'1.14.3
【推薦】
在同一個文件中,保持使用字符串引號的一致性。使用單引號'
或者雙引號
"
引用字符串,并在同一文件中一直沿用這種風(fēng)格。當(dāng)字符串中包含單引號或者雙引號時,為提高可讀性,使用另外一種引號,代替轉(zhuǎn)義字符。正確示范Python('Why
are
you
hiding
your
eyes?')
Gollum("I'm
scared
of
lint
errors.")
Narrator('"Good!"
thought
a
happy
Python
reviewer.')錯誤示范Python("Why
are
you
hiding
your
eyes?")
Gollum('The
lint.
It
burns.
It
burns
us.')
Gollum("Always
the
great
lint.
Watching.
Watching.")1.14.4
【必須】
如果要引用的字符串為多行時,需要使用雙引號引用字符串。1.14.5
【必須】
文檔字符串(docstring)必須使用三重雙引號
"""。1.14.6
【可選】
避免在代碼中使用三重引號
""",因?yàn)楫?dāng)使用三重引號時,縮進(jìn)方式與其他部分不一致,容易引起誤導(dǎo)。正確示范print("This
is
much
nicer.\n"
"Do
it
this
way.\n")錯誤示范print("""This
is
pretty
ugly.
Don't
do
this.
""")1.14.7
【推薦】
檢查前綴和后綴時,使用
.startswith()
和
.endswith()
代替字符串切片。正確示范if
foo.startswith('bar'):錯誤示范if
foo[:3]
==
'bar':1.15文件和sockets1.15.1
【必須】
在文件和sockets結(jié)束時,顯式的關(guān)閉它。除文件外,sockets或其他類似文件的對象在沒有必要的情況下打開,會有許多副作用,例如:它們可能會消耗有限的系統(tǒng)資源,如文件描述符。如果這些資源在使用后沒有及時歸還系統(tǒng),那么用于處理這些對象的代碼會將資源消耗殆盡。持有文件將會阻止對于文件的其他諸如移動、刪除之類的操作。僅僅是從邏輯上關(guān)閉文件和sockets,那么它們?nèi)匀豢赡軙黄涔蚕淼某绦蛟跓o意中進(jìn)行讀或者寫操作。只有當(dāng)它們真正被關(guān)閉后,對于它們嘗試進(jìn)行讀或者寫操作將會拋出異常,并使得問題快速顯現(xiàn)出來。而且,幻想當(dāng)文件對象析構(gòu)時,文件和sockets會自動關(guān)閉,試圖將文件對象的生命周期和文件的狀態(tài)綁定在一起的想法,都是不現(xiàn)實(shí)的。因?yàn)橛腥缦略颍簺]有任何方法可以確保運(yùn)行環(huán)境會真正的執(zhí)行文件的析構(gòu)。不同的Python實(shí)現(xiàn)采用不同的內(nèi)存管理技術(shù),比如延時垃圾處理機(jī)制。延時垃圾處理機(jī)制可能會導(dǎo)致對象生命周期被任意無限制的延長。對于文件意外的引用,會導(dǎo)致對于文件的持有時間超出預(yù)期(比如對于異常的跟蹤,包含有全局變量等)。1.15.2
【推薦】
推薦使用
with
語句管理文件。with
open("hello.txt")
as
hello_file:
for
line
in
hello_file:
print(line)對于不支持使用
with
語句的類似文件的對象,使用
contextlib.closing():import
contextlib
with
contextlib.closing(urllib.urlopen("/"))
as
front_page:
for
line
in
front_page:
print(line)LegacyAppEngine中Python2.5的代碼如使用
with
語句,需要添加
from__future__importwith_statement.1.16訪問控制在Python中,對于瑣碎又不太重要的訪問函數(shù),應(yīng)該直接使用公有變量來取代它們,這樣可以避免額外的函數(shù)調(diào)用開銷。當(dāng)添加更多功能時,也可以用屬性(property)來保持語法的一致性。1.16.1
【推薦】
如果訪問屬性后需要復(fù)雜的邏輯處理,或者變量的訪問開銷很顯著,那么應(yīng)該使用像
get_foo()
和
set_foo()
這樣的函數(shù)調(diào)用。如果之前的代碼行為已經(jīng)通過屬性(property)訪問,那么就不要將新的訪問函數(shù)與屬性綁定。否則,任何試圖通過老方法訪問變量的代碼就沒法運(yùn)行,使用者也就會意識到復(fù)雜性發(fā)生了變化。(如果可以重構(gòu)這個代碼是最好的了)1.17Main即使是一個打算被用作腳本的文件,也應(yīng)該是可導(dǎo)入的。并且簡單的導(dǎo)入不應(yīng)該導(dǎo)致這個腳本的主功能(mainfunctionality)被執(zhí)行,這是一種副作用。主功能應(yīng)該放在一個main()函數(shù)中。1.17.1
【必須】
所有的文件都應(yīng)該可以被導(dǎo)入。對不需要作為程序入口地方添加
if__name__=='__main__'
。在Python中,pydoc以及單元測試要求模塊必須是可導(dǎo)入的。你的代碼應(yīng)該在執(zhí)行主程序前總是檢查
if__name__=='__main__'
,這樣當(dāng)模塊被導(dǎo)入時主程序就不會被執(zhí)行。所有的頂級代碼在模塊導(dǎo)入時都會被執(zhí)行。要小心不要去調(diào)用函數(shù),創(chuàng)建對象,或者執(zhí)行那些不應(yīng)該在使用pydoc時執(zhí)行的操作。正確示范def
main():
...
if
__name__
==
'__main__':
main()1.18命名module_name,package_name,ClassName,method_name,ExceptionName,function_name,GLOBAL_VAR_NAME,instance_var_name,function_parameter_name,local_var_name.應(yīng)該避免的名稱:單字符名稱,除了計數(shù)器和迭代器。包/模塊名中的連字符(-)。雙下劃線開頭并結(jié)尾的名稱(Python保留,例如__init__)。1.18.1
【推薦】
命名約定規(guī)則如下:pylint:invalid-name.所謂內(nèi)部(Internal)
表示僅模塊內(nèi)可用,或者,在類內(nèi)是保護(hù)或私有的。用單下劃線
(_)
開頭表示模塊變量或函數(shù)是protected的(使用frommoduleimport*時不會包含)。用雙下劃線
(__)
開頭的實(shí)例變量或方法表示類內(nèi)私有。將相關(guān)的類和頂級函數(shù)放在同一個模塊里。不像Java,沒必要限制一個類一個模塊。對類名使用大寫字母開頭的單詞(如CapWords,即Pascal風(fēng)格),但是模塊名應(yīng)該用小寫加下劃線的方式(如lower_with_under.py)。盡管已經(jīng)有很多現(xiàn)存的模塊使用類似于CapWords.py這樣的命名,但現(xiàn)在已經(jīng)不鼓勵這樣做,因?yàn)槿绻K名碰巧和類名一致,這會讓人困擾。Python之父Guido推薦的規(guī)范:TypePublicInternalModuleslower_with_under_lower_with_underPackageslower_with_underClassesCapWords_CapWordsExceptionsCapWordsFunctionslower_with_under()_lower_with_under()Global/ClassConstantsCAPS_WITH_UNDER_CAPS_WITH_UNDERGlobal/ClassVariableslower_with_under_lower_with_underInstanceVariableslower_with_under_lower_with_under(protected)or__lower_with_under(private)MethodNameslower_with_under()_lower_with_under()(protected)or__lower_with_under()(private)Function/MethodParameterslower_with_underLocalVariableslower_with_under二、編碼規(guī)范2.1三目運(yùn)算符2.1.1
【必須】
三目操作符判斷,python不支持三目運(yùn)算符,但可使用如下方式,禁止使用復(fù)雜難懂的邏輯判斷。正確示范x
=
a
if
a
>=
b
else
b錯誤示范x
=
a
>=
b
and
a
or
b2.2None條件的判斷2.2.1
【必須】
為提升可讀性,在判斷條件中應(yīng)使用
isnot,而不使用
not...is。pycodestyle:E714testforobjectidentityshouldbe'isnot'.正確示范if
foo
is
not
None:錯誤示范if
not
foo
is
None:2.3lambda匿名函數(shù)2.3.1
【必須】
使用def定義簡短函數(shù)而不是使用lambda。pycodestyle:E731donotassignalambdaexpression,useadef.使用def的方式有助于在trackbacks中打印有效的類型信息,明確使用
f
函數(shù)而不是一個lambda的調(diào)用。正確示范def
f(x):
return
2
*
x錯誤示范f
=
lambda
x:
2
*
x2.4異常2.4.1
【必須】
異常類繼承自
Exception,而不是
BaseException。2.4.2
【必須】
使用新版本拋出異常的方式,禁止使用廢棄的方式。pycodestyle:W602deprecatedformofraisingexception.正確示范raise
ValueError('message')錯誤示范raise
ValueError,
'message'2.4.3
【必須】
捕獲異常時,需要指明具體異常,而不是捕獲所有異常。除非已經(jīng)在當(dāng)前線程的最外層(記得還是要打印一條traceback)。pylint:broad-except,
bare-except.正確示范try:
import
platform_specific_module
except
ImportError:
platform_specific_module
=
None
try:
do_something()
except
Exception
as
ex:
#
pylint:
disable=broad-except
log.exception(ex)
#
應(yīng)將錯誤堆棧打印到日志文件中,以供后續(xù)排查。
handle_exception_or_not()
#
除打印日志外,還可以進(jìn)一步處理如清理資源等,可選。錯誤示范try:
import
platform_specific_module
except
Exception:
#
broad-except
platform_specific_module
=
None
try:
do_something()
except
Exception:
#
框架等未明確異常場景,建議增加
traceback
打印
pass2.4.4
【推薦】
建議在代碼中用異常替代函數(shù)的錯誤返回碼。正確示范def
write_data():
if
check_file_exist():
do_something()
else:
raise
FileNotExist()錯誤示范def
write_data():
if
check_file_exist():
do_something()
return
0
else:
return
FILE_NOT_EXIST2.4.5
【推薦】
在
except
子句中重新拋出原有異常時,不能用
raiseex,而是用
raise。正確示范try:
raise
MyException()
except
MyException
as
ex:
try_handle_exception()
raise
#
可以保留原始的
traceback
try:
raise
MyException()
except
MyException
as
ex:
log.exception(ex)
raise
AnotherException(str(ex))
#
允許的,建議保留好之前的異常棧信息,用于定位問題錯誤示范try:
raise
MyException()
except
MyException
as
ex:
try_handle_exception()
raise
ex
#
異常棧信息從這里開始,原始的raise異常棧信息消息2.4.6
【推薦】
所有
try/except
子句的代碼要盡可的少,以免屏蔽其他的錯誤。正確示范try:
value
=
collection[key]
except
KeyError:
return
key_not_found(key)
else:
return
handle_value(value)錯誤示范try:
#
范圍太廣
return
handle_value(collection[key])
except
KeyError:
#
會捕捉到
handle_value()
中的
KeyError
return
key_not_found(key)2.5條件表達(dá)式2.5.1
【推薦】
函數(shù)或者方法在沒有返回時要明確返回
None。pylint:inconsistent-return-statements.正確示范def
foo(x):
if
x
>=
0:
return
math.sqrt(x)
else:
return
None
def
bar(x):
if
x
<
0:
return
None
return
math.sqrt(x)錯誤示范def
foo(x):
if
x
>=
0:
return
math.sqrt(x)
def
bar(x):
if
x
<
0:
return
return
math.sqrt(x)2.5.2
【推薦】
對于未知的條件分支或者不應(yīng)該進(jìn)入的分支,建議拋出異常,而不是返回一個值(比如說
None
或
False)。正確示范def
f(x):
if
x
in
('SUCCESS',):
return
True
else:
raise
MyException()
#
如果一定不會走到的條件,可以增加異常,防止將來未知的語句執(zhí)行。錯誤示范def
f(x):
if
x
in
('SUCCESS',):
return
True
return
None2.5.3
【可選】
if
與
else
盡量一起出現(xiàn),而不是全部都是
if
子句。正確示范if
condition:
do_something()
else:
#
增加說明注釋
pass
if
condition:
do_something()
#
這里增加注釋說明為什么不用寫else子句
#
else:
#
pass錯誤示范if
condition:
do_something()
if
another_condition:
#
不能確定是否筆誤為
elif
,還是開啟全新一個if條件
do_another_something()
else:
do_else_something()2.6True/False布爾運(yùn)算2.6.1
【必須】
不要用
==
與
True、
False
進(jìn)行布爾運(yùn)算。pylint:singleton-comparison.正確示范if
greeting:
pass錯誤示范if
greeting
==
True:
pass
if
greeting
is
True:
#
Worse
pass2.6.2
【必須】
對序列(字符串、列表、元組),空序列為false的情況。pylint:len-as-condition.正確示范if
not
seq:
pass
if
seq:
pass錯誤示范if
len(seq):
pass
if
not
len(seq):
pass2.7列表推導(dǎo)式2.7.1
【必須】
禁止超過1個for語句或過濾器表達(dá)式,否則使用傳統(tǒng)
for
循環(huán)語句替代。正確示范number_list
=
[1,
2,
3,
10,
20,
55]
odd
=
[i
for
i
in
number_list
if
i
%
2
==
1]
result
=
[]
for
x
in
range(10):
for
y
in
range(5):
if
x
*
y
>
10:
result.append((x,
y))錯誤示范result
=
[(x,
y)
for
x
in
range(10)
for
y
in
range(5)
if
x
*
y
>
10]
#
for
語句2.7.2
【推薦】
列表推導(dǎo)式適用于簡單場景。如果語句過長,每個部分應(yīng)該單獨(dú)置于一行:映射表達(dá)式,for語句,過濾器表達(dá)式。正確示范fizzbuzz
=
[]
for
n
in
range(100):
if
n
%
3
==
0
and
n
%
5
==
0:
fizzbuzz.append(f'fizzbuzz
{n}')
elif
n
%
3
==
0:
fizzbuzz.append(f'fizz
{n}')
elif
n
%
5
==
0:
fizzbuzz.append(f'buzz
{n}')
else:
fizzbuzz.append(n)
for
n
in
range(1,
11):
print(n)錯誤示范#
條件過于復(fù)雜,應(yīng)該采用for語句展開
fizzbuzz
=
[
f'fizzbuzz
{n}'
if
n
%
3
==
0
and
n
%
5
==
0
else
f'fizz
{n}'
if
n
%
3
==
0
else
f'buzz
{n}'
if
n
%
5
==
0
else
n
for
n
in
range(100)
]
[print(n)
for
n
in
range(1,
11)]
#
無返回值2.8函數(shù)2.8.1
【必須】
模塊內(nèi)部禁止定義重復(fù)函數(shù)聲明。pylint:function-redefined.禁止重復(fù)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 【正版授權(quán)】 IEC 61188-6-3:2024 EN-FR Circuit boards and circuit board assemblies - Design and use - Part 6-3: Land pattern design - Description of land pattern for through hole componen
- 2025-2030年中國飲用水行業(yè)現(xiàn)狀分析及投資十三五規(guī)劃研究報告
- 2025-2030年中國陸上貨物運(yùn)輸保險市場運(yùn)行狀況及發(fā)展風(fēng)險評估報告
- 2025湖南省建筑安全員-B證考試題庫及答案
- 2025-2030年中國鋁合金型材市場十三五規(guī)劃及發(fā)展建議分析報告
- 2025-2030年中國營林及木竹采伐機(jī)械制造產(chǎn)業(yè)需求分析及發(fā)展?fàn)顩r預(yù)測報告
- 2025-2030年中國航模行業(yè)競爭格局及投資戰(zhàn)略研究報告
- 2025-2030年中國羅漢果茶市場發(fā)展現(xiàn)狀及前景規(guī)劃研究報告
- 2025-2030年中國紅薯淀粉市場運(yùn)營狀況及前景預(yù)測分析報告
- 2025-2030年中國端氨基聚醚行業(yè)風(fēng)險評估及發(fā)展策略研究報告
- 2025春季開學(xué)前學(xué)校安全隱患排查工作實(shí)施方案:5大安全排查一個都不能少
- 威圖電柜空調(diào)SK3304500使用說書
- 人教版小學(xué)三年級道德與法治下冊全冊教案(精品)
- 2022年RDA5807m+IIC收音機(jī)51單片機(jī)C程序上課講義
- 雅馬哈貼片機(jī)_修機(jī)_調(diào)機(jī)的經(jīng)驗(yàn)之談1
- 全自動咖啡機(jī)基本結(jié)構(gòu)及原理教程課件
- 金屬風(fēng)管支架重量計算表
- 正負(fù)零以下基礎(chǔ)施工方案(44頁)
- 簡愛人物形象分析(課堂PPT)
- 義務(wù)教育《勞動》課程標(biāo)準(zhǔn)(2022年版)
- 從業(yè)務(wù)骨干到管理者(課堂PPT)
評論
0/150
提交評論