![Python編碼規(guī)范匯編_第1頁](http://file4.renrendoc.com/view/925ec3ca2d5315ccdd093d12ce42e17e/925ec3ca2d5315ccdd093d12ce42e17e1.gif)
![Python編碼規(guī)范匯編_第2頁](http://file4.renrendoc.com/view/925ec3ca2d5315ccdd093d12ce42e17e/925ec3ca2d5315ccdd093d12ce42e17e2.gif)
![Python編碼規(guī)范匯編_第3頁](http://file4.renrendoc.com/view/925ec3ca2d5315ccdd093d12ce42e17e/925ec3ca2d5315ccdd093d12ce42e17e3.gif)
![Python編碼規(guī)范匯編_第4頁](http://file4.renrendoc.com/view/925ec3ca2d5315ccdd093d12ce42e17e/925ec3ca2d5315ccdd093d12ce42e17e4.gif)
![Python編碼規(guī)范匯編_第5頁](http://file4.renrendoc.com/view/925ec3ca2d5315ccdd093d12ce42e17e/925ec3ca2d5315ccdd093d12ce42e17e5.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
Python編碼規(guī)范匯編前言:為了讓不同編碼習慣的開發(fā)者更好的協(xié)作配合,并且形成良好的基礎編碼規(guī)范與風格,我們以PEP8為基礎,修改了陳舊的規(guī)則,豐富了示例,并整理了工作中常見的不規(guī)范操作,最終形成此Python編碼規(guī)范與風格。一、編碼風格1.1縮進1.2每行最大長度1.3空白符1.4操作符1.5括號1.6空行1.7源文件編碼1.8Shebang1.9模塊引用(import)1.10模塊中的魔術變量(dunders)1.11注釋1.12文檔字符串1.13類型提示1.14字符串1.15文件和sockets1.16訪問控制1.17Main1.18命名二、編碼規(guī)范2.1三目運算符2.2None條件的判斷2.3lambda匿名函數(shù)2.4異常2.5條件表達式2.6True/False布爾運算2.7列表推導式2.8函數(shù)2.9變量工具與配置flake8pylintblackEditorConfig注意事項本規(guī)范適用于所有使用Python語言作為開發(fā)語言的軟件產品。由于Python2在2020年停止維護,建議新增的項目使用Python3.6+,可以使用到更多的高級特性。如果項目有兼容性需求需要支持老版本Python的,那么不涉及的特性可以忽略。本規(guī)范的示例采用符合Python3.6+的語法。必須(Mandatory):用戶必須采用;推薦(Preferable):用戶理應采用,但如有特殊情況,可以不采用;可選(Optional):用戶可參考,自行決定是否采用;未明確指明的則默認為
必須(Mandatory)。一、編碼風格規(guī)范地代碼布局有助于幫助開發(fā)者更容易地理解業(yè)務邏輯。1.1縮進1.1.1
【必須】
對于每級縮進,統(tǒng)一要求使用4個空格,而非tab鍵。pylint:bad-indentation.1.1.2
【必須】
續(xù)行,要求使用括號等定限界符,并且需要垂直對齊。正確示范#
與定界(括號)符對齊
foo
=
long_function_name(var_one,
var_two,
var_three,
var_four)
#
換行并增加4個額外的空格(一級縮進)
def
long_function_name(
var_one,
var_two,
var_three,
var_four):
print(var_one)
#
懸掛需要增加一級縮進
foo
=
long_function_name(
var_one,
var_two,
var_three,
var_four)錯誤示范
#
當不使用垂直對齊時,第一行不允許加參數(shù)
foo
=
long_function_name(var_one,
var_two,
var_three,
var_four)
#
下面這種情況,需要增加額外的縮進,否則無法區(qū)分代碼所在的縮進級別
def
long_function_name(
var_one,
var_two,
var_three,
var_four):
print(var_one)1.1.3
【推薦】
如果包含定界符(括號,中括號,大括號)的表達式跨越多行,那么定界符的擴回符,可以放置與最后一行的非空字符對齊或者與構造多行的開始第一個字符對齊。正確示范#
與最后一行的非空字符對齊
my_list
=
[
1,
2,
3,
4,
5,
6,
]
result
=
some_function_that_takes_arguments(
'a',
'b',
'c',
'd',
'e',
'f',
)
#
或者與開始構造多行的第一個字符對齊
my_list
=
[
1,
2,
3,
4,
5,
6,
]
result
=
some_function_that_takes_arguments(
'a',
'b',
'c',
'd',
'e',
'f',
)1.1.4
【推薦】
對于會經常改動的函數(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,
#
可能經常增加字段
}錯誤示范#
關鍵字會不斷增加,每個元素都換行
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ù)行中,增加額外的縮進級別。允許and操作符在前
if
(this_is_one_thing
and
that_is_another_thing):
do_something()
#
更推薦:在續(xù)行中,增加額外的縮進級別
if
(this_is_one_thing
and
that_is_another_thing):
do_something()
#
允許:與定界符(括號)對齊,不需要額外的縮進
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
個字符。每行代碼最大長度限制的根本原因是過長的行會導致閱讀障礙,使得縮進失效。pylint:line-too-long.除了以下兩種情況例外:導入模塊語句。注釋中包含的URL。如果需要一個長的字符串,可以用括號實現(xiàn)隱形連接。正確示范x
=
('This
will
build
a
very
long
long
'
'long
long
long
long
long
long
string')1.3空白符1.3.1
【必須】
在表達式的賦值符號、操作符左右至少有一個空格。正確示范x
=
y
+
1錯誤示范x=y+1
x
=
y+11.3.2
【必須】
禁止行尾空白。pylint:trailing-whitespace.行尾空白雖然不會造成功能性異常,但是這些空白字符會被源碼管理系統(tǒng)標記出來顯示為差異,對開發(fā)人員造成困惱。正確示范#
YES:
尾部沒有空白符號
+
para
=
{}
+
para
=
{}
#
comment錯誤示范#
No:
結尾存在多余空白符號
-
para
=
{}?????
-
para
=
{}
#
comment??????1.4操作符1.4.1
【推薦】
Python沒有三目操作符,對于二目操作符來說,操作符允許在換行符之后出現(xiàn)。備注:pycodestyle工具與此條目相反,PEP8推薦操作符在這之前,更具備可讀性。PEP8:ShouldaLineBreakBeforeorAfteraBinaryOperator?。屏蔽pycodestyle:W503linebreakbeforebinaryoperator正確示范#
YES:
易于將運算符與操作數(shù)匹配,可讀性高
income
=
(gross_wages
+
taxable_interest
+
(dividends
-
qualified_dividends)
-
ira_deduction
-
student_loan_interest)錯誤示范#
No:
運算符的位置遠離其操作數(shù)
income
=
(gross_wages
+
taxable_interest
+
(dividends
-
qualified_dividends)
-
ira_deduction
-
student_loan_interest)1.5括號1.5.1
【必須】
tuple元組不允許逗號結尾,顯式增加括號規(guī)避。即使一個元素也加上括號。pylint:trailing-comma-tuple.行尾的逗號可能導致本來要定義一個簡單變量,結果變成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
【必須】
源文件須使用且僅使用
一個換行符
作為結尾。pylint:missing-final-newline,
trailing-newlines.1.6.4
【必須】
通常每個語句應該獨占一行。pylint:multiple-statements.如果測試結果與測試語句在一行放得下,你也可以將它們放在同一行。如果是
if
語句,只有在沒有
else
時才能這樣做。特別地,絕不要對
try/except
這樣做,因為
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è)務邏輯塊。"""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
編碼,以下內容需要增加到每一個python文件的頭部。#
-*-
coding:
utf-8
-*-1.7.2
【必須】
**避免不同操作系統(tǒng)對文件換行處理的方式不同,一律使用
LF**。pylint:mixed-line-endings,
unexpected-line-ending-format.1.8Shebang1.8.1
【必須】
程序的main文件應該以
#!/usr/bin/envpython2
或者
#!/usr/bin/envpython3
開始,可以同時支持Python2、Python3的#!/usr/bin/envpython。非程序入口的文件不應該出現(xiàn)Shebang。正確示范#!/usr/bin/env
python3
#
-*-
coding:
utf-8
-*-
#1.9模塊引用(import)1.9.1
【必須】
每個導入應該獨占一行。pylint:multiple-imports.正確示范import
os
import
sys錯誤示范import
os,
sys1.9.2
【必須】
導入總應該放在文件頂部,位于模塊注釋和文檔字符串之后,模塊全局變量和常量之前。pylint:wrong-import-order.導入應該按照從最通用到最不通用的順序分組,每個分組之間,需要空一行:標準庫導入第三方庫導入本地導入每種分組中,建議每個模塊的完整包路徑按
字典序
排序,并忽略大小寫。正確示范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*,因為可能會造成命名空間的污染。pylint:wildcard-import.1.9.4
【必須】
禁止導入了模塊卻不使用它。pylint:unused-import.正確示范import
os
#
used
dir_path
=
os.path.abspath('.')錯誤示范import
os
#
unused
!
#
dir_path
=
os.path.abspath('.')1.10模塊中的魔術變量(dunders)1.10.1
【必須】
對于兩個
_
開頭和兩個
_
結尾的變量,如
__all__,__author__,__version__等,應該放在模塊文檔之后,其他模塊導入之前(__future__
除外)。1.10.2
【必須】
Python要求
future
導入必須出現(xiàn)在其他模塊導入之前。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ù),方法,以及行內注釋的都有各自的風格。1.11.1
【必須】
所有#開頭的注釋,必須與所在的代碼塊同級,并置放在代碼之上。pycodestyle:E262inlinecommentshouldstartwith'#'.1.11.2
【必須】
注釋的每一行都應該以#和一個空格開頭。pycodestyle:E266toomanyleading'#'forblockcomment,
E262inlinecommentshouldstartwith'#'.1.11.3
【必須】
行內注釋#與代碼離開至少2個空格。pycodestyle:E261atleasttwospacesbeforeinlinecomment.1.11.4
【必須】
塊注釋:對于復雜的操作,可以在代碼之前寫若干行注釋,對簡單的代碼,可以放在行內。與代碼離開至少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注釋應該在所有開頭處包含
TODO
字符串,緊跟著是用括號括起來的你的名字,email地址或其它標識符,然后是一個可選的冒號。接著必須有一行注釋,解釋要做什么。主要目的是為了有一個統(tǒng)一的TODO格式,這樣添加注釋的人就可以搜索到(并可以按需提供更多細節(jié))。寫了TODO注釋并不保證寫的人會親自解決問題。當你寫了一個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ù),類和方法相關聯(lián)的便捷方法。def
foobar():
"""Return
a
foobang
Optional
plotz
says
to
frobnicate
the
bizbaz
first.
"""PEP257全面描述了文檔字符串的風格。1.12.1
【推薦】
需對外發(fā)布的public模塊,函數(shù),類,方法等需要包含文檔字符串。內部使用的方法,函數(shù)等,要求使用簡單的注釋描述功能。pylint:missing-module-docstring,
missing-class-docstring,
missing-function-docstring.一個函數(shù)或方法,如果可以直接被其他開發(fā)者使用,需要提供文檔明確其含義,需要指出輸入,輸出,以及異常內容。1.12.2
【必須】
第一行應為文檔名,空一行后,輸入文檔描述。1.12.3
【推薦】
在使用文檔字符串時,推薦使用
reStructuredText
風格類型。正確示范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
【推薦】
類應該在其定義下有一個用于描述該類的文檔字符串。如果類有公共屬性(Attributes),那么文檔中應該有一個屬性(Attributes)段,并且應該遵守和函數(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)語言,在運行時無需指定變量類型。雖然運行時不會執(zhí)行函數(shù)與變量類型注解,但類型提示有助于閱讀代碼、重構、靜態(tài)代碼檢查與IDE的語法提示。推薦在項目中使用該特性。更多使用可以參考類型標注支持。類型提示示例代碼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
【必須】
模塊級變量,類和實例變量以及局部變量的注釋應在冒號后面有一個空格。pycodestyle:E231missingwhitespaceafter':'.1.13.2
【必須】
冒號前不應有空格。1.13.3
【必須】
如果有賦值符,則等號在兩邊應恰好有一個空格。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
【推薦】
當使用類型提示出現(xiàn)循環(huán)引用時,可以在導入的頭部使用
iftyping.TYPE_CHECKING
,且對類型注解使用雙引號或單引號進行修飾。正確示范import
typing
if
typing.TYPE_CHECKING:
#
運行時不導入
#
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ù)都是字符串,也要使用%操作符或者格式化方法格式化字符串。不過也不能一概而論,你需要在+和%之間權衡。正確示范#
更推薦
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)建不必要的臨時對象,并且導致二次方而不是線性的運行時間。作為替代方案,你可以將每個子串加入列表,然后在循環(huán)結束后用
.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
【推薦】
在同一個文件中,保持使用字符串引號的一致性。使用單引號'
或者雙引號
"
引用字符串,并在同一文件中一直沿用這種風格。當字符串中包含單引號或者雙引號時,為提高可讀性,使用另外一種引號,代替轉義字符。正確示范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
【可選】
避免在代碼中使用三重引號
""",因為當使用三重引號時,縮進方式與其他部分不一致,容易引起誤導。正確示范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結束時,顯式的關閉它。除文件外,sockets或其他類似文件的對象在沒有必要的情況下打開,會有許多副作用,例如:它們可能會消耗有限的系統(tǒng)資源,如文件描述符。如果這些資源在使用后沒有及時歸還系統(tǒng),那么用于處理這些對象的代碼會將資源消耗殆盡。持有文件將會阻止對于文件的其他諸如移動、刪除之類的操作。僅僅是從邏輯上關閉文件和sockets,那么它們仍然可能會被其共享的程序在無意中進行讀或者寫操作。只有當它們真正被關閉后,對于它們嘗試進行讀或者寫操作將會拋出異常,并使得問題快速顯現(xiàn)出來。而且,幻想當文件對象析構時,文件和sockets會自動關閉,試圖將文件對象的生命周期和文件的狀態(tài)綁定在一起的想法,都是不現(xiàn)實的。因為有如下原因:沒有任何方法可以確保運行環(huán)境會真正的執(zhí)行文件的析構。不同的Python實現(xiàn)采用不同的內存管理技術,比如延時垃圾處理機制。延時垃圾處理機制可能會導致對象生命周期被任意無限制的延長。對于文件意外的引用,會導致對于文件的持有時間超出預期(比如對于異常的跟蹤,包含有全局變量等)。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ù),應該直接使用公有變量來取代它們,這樣可以避免額外的函數(shù)調用開銷。當添加更多功能時,也可以用屬性(property)來保持語法的一致性。1.16.1
【推薦】
如果訪問屬性后需要復雜的邏輯處理,或者變量的訪問開銷很顯著,那么應該使用像
get_foo()
和
set_foo()
這樣的函數(shù)調用。如果之前的代碼行為已經通過屬性(property)訪問,那么就不要將新的訪問函數(shù)與屬性綁定。否則,任何試圖通過老方法訪問變量的代碼就沒法運行,使用者也就會意識到復雜性發(fā)生了變化。(如果可以重構這個代碼是最好的了)1.17Main即使是一個打算被用作腳本的文件,也應該是可導入的。并且簡單的導入不應該導致這個腳本的主功能(mainfunctionality)被執(zhí)行,這是一種副作用。主功能應該放在一個main()函數(shù)中。1.17.1
【必須】
所有的文件都應該可以被導入。對不需要作為程序入口地方添加
if__name__=='__main__'
。在Python中,pydoc以及單元測試要求模塊必須是可導入的。你的代碼應該在執(zhí)行主程序前總是檢查
if__name__=='__main__'
,這樣當模塊被導入時主程序就不會被執(zhí)行。所有的頂級代碼在模塊導入時都會被執(zhí)行。要小心不要去調用函數(shù),創(chuàng)建對象,或者執(zhí)行那些不應該在使用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.應該避免的名稱:單字符名稱,除了計數(shù)器和迭代器。包/模塊名中的連字符(-)。雙下劃線開頭并結尾的名稱(Python保留,例如__init__)。1.18.1
【推薦】
命名約定規(guī)則如下:pylint:invalid-name.所謂內部(Internal)
表示僅模塊內可用,或者,在類內是保護或私有的。用單下劃線
(_)
開頭表示模塊變量或函數(shù)是protected的(使用frommoduleimport*時不會包含)。用雙下劃線
(__)
開頭的實例變量或方法表示類內私有。將相關的類和頂級函數(shù)放在同一個模塊里。不像Java,沒必要限制一個類一個模塊。對類名使用大寫字母開頭的單詞(如CapWords,即Pascal風格),但是模塊名應該用小寫加下劃線的方式(如lower_with_under.py)。盡管已經有很多現(xiàn)存的模塊使用類似于CapWords.py這樣的命名,但現(xiàn)在已經不鼓勵這樣做,因為如果模塊名碰巧和類名一致,這會讓人困擾。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三目運算符2.1.1
【必須】
三目操作符判斷,python不支持三目運算符,但可使用如下方式,禁止使用復雜難懂的邏輯判斷。正確示范x
=
a
if
a
>=
b
else
b錯誤示范x
=
a
>=
b
and
a
or
b2.2None條件的判斷2.2.1
【必須】
為提升可讀性,在判斷條件中應使用
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的調用。正確示范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
【必須】
捕獲異常時,需要指明具體異常,而不是捕獲所有異常。除非已經在當前線程的最外層(記得還是要打印一條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)
#
應將錯誤堆棧打印到日志文件中,以供后續(xù)排查。
handle_exception_or_not()
#
除打印日志外,還可以進一步處理如清理資源等,可選。錯誤示范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條件表達式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
【推薦】
對于未知的條件分支或者不應該進入的分支,建議拋出異常,而不是返回一個值(比如說
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布爾運算2.6.1
【必須】
不要用
==
與
True、
False
進行布爾運算。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列表推導式2.7.1
【必須】
禁止超過1個for語句或過濾器表達式,否則使用傳統(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
【推薦】
列表推導式適用于簡單場景。如果語句過長,每個部分應該單獨置于一行:映射表達式,for語句,過濾器表達式。正確示范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)錯誤示范#
條件過于復雜,應該采用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
【必須】
模塊內部禁止定義重復函數(shù)聲明。pylint:function-redefined.禁止重復
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024-2030年中國外貿服飾行業(yè)發(fā)展?jié)摿︻A測及投資戰(zhàn)略研究報告
- 2025年度家具品牌授權合作協(xié)議-@-1
- 2025年中國銀行自助服務終端行業(yè)全景評估及投資規(guī)劃建議報告
- 2025年度建筑工地臨時施工合同(綠色建筑認證)
- 權益部申請書
- 2025年可達靈片項目可行性研究報告
- 2025年中國重型自卸汽車行業(yè)發(fā)展監(jiān)測及投資戰(zhàn)略規(guī)劃研究報告
- 食品泡罩包裝機行業(yè)深度研究報告
- 2025年數(shù)碼攝錄一體機項目投資可行性研究分析報告
- 打造未來消費場景的全新實施方案
- 基于單片機的交通燈控制系統(tǒng)設計畢業(yè)論文
- 2024年執(zhí)業(yè)醫(yī)師考試-醫(yī)師定期考核(口腔)筆試參考題庫含答案
- 中國律師學 課件 陳衛(wèi)東 第10-17章 律師收費制度-律師非訴訟業(yè)務(二)
- (高清版)TDT 1040-2013 土地整治項目制圖規(guī)范
- 中國移動行測測評題及答案
- 精神科患者服藥依從性健康宣教
- 設備維保的維修流程與指導手冊
- 急性腎小球腎炎病人護理課件
- 招標代理服務的關鍵流程與難點解析
- GB/T 5465.2-2023電氣設備用圖形符號第2部分:圖形符號
- 《三國演義》中的佛教文化:以黃承兒為例
評論
0/150
提交評論