《(完整版)Python开发编码规范.docx》由会员分享,可在线阅读,更多相关《(完整版)Python开发编码规范.docx(23页珍藏版)》请在课桌文档上搜索。
1、Python开发编码规范代码的布局31o1缩进31.2 制表符还是空格?31.3 行的最大长度31o4空行4编码51.1 导入51.2 空格61.3 3其它建议(OtherRecommendations)81.4 注释102o4.1注释块112o4.2行内注释112o5文档化121.6 版本注记141.7 命名约定152. 7.1描述:命名风格162o7o2说明:命名约定173. 7.3应避免的名字1827o301模块名(ModuleNames)1827.3.2类名(CIaSSNames)182o703.3异常名(ExceptionNames)192.73o4全局变量名(GlobalVaria
2、bIeNames)192.7o3.5函数名(FUnCtiOnNames)192.7.36方法名和实例变量(MethodNamesandInstanceVariables)192o703.7继承的设计(DeSigningforinheritance)20设计建议(ProgrammingRecommendations)211代码的布局1.1 缩进使用Emacs的Python-mode的默认值:4个空格一个缩进层次。对于确实古老的代码,你不希望产生混乱,可以继续使用8空格的制表符(8-spacetabs)oEmacsPython-mode自动发现文件中主要的缩进层次,依此设定缩进参数.1.2 制表符
3、还是空格?永远不要混用制表符和空格。最流行的Python缩进方式是仅使用空格,其次是仅使用制表符。混合着制表符和空格缩进的代码将被转换成仅使用空格。(在Emacs中,选中整个缓冲区,按ESC-X去除制表符(Untabify)。)调用PythOn命令行解释器时使用一t选项,可对代码中不合法得混合制表符和空格发出警告(warnings)o使用-tt时警告(WarningS)将变成错误(errors).这些选项是被高度推荐的。对于新的项目,强烈推荐仅使用空格(spaces-only)而不是制表符.许多编辑器拥有使之易于实现的功能。(在EmaCS中,确认indent-tabs-mode是niI)。1.
4、3 行的最大长度周围仍然有许多设备被限制在每行80字符;而且,窗口限制在80个字符使将多个窗口并排放置成为可能。在这些设备上使用默认的折叠(WraPPing)方式看起来有点丑陋.因此,请将所有行限制在最大79字符(ErTlaCS准确得将行限制为长80字符),对顺序排放的大块文本(文档字符串或注释),推荐将长度限制在72字符。折叠长行的首选方法是使用Pyhon支持的圆括号,方括号(brackets)和花括号(braces)内的行延续。如果需要,你可以在表达式周围增加一对额外的圆括号,但是有时使用反斜杠看起来更好.确认恰当得缩进了延续的行。Emacs的Python-mode正确得完成了这些.一些例
5、子:ToggleIinenumberscIassRectangle(Blob):23 def_init_(seIf,width,height,4coIor=fbIack,emphasis=None,highIight-0):5 ifwidth=0andheight=0and8Or=redandephasis=,strongorhighIight100:6 raiseVaIueError,“sorry,youlose7 ifwidth=0andheight=0and(coIor=red,or8emphasisisNone):9 raiseVaIueError,Idontthinkso”10 Bl
6、obo_init_(seIf,width,height,11 color,emphasis,highIight)1.4空行用两行空行分割顶层函数和类的定义,类内方法的定义用单个空行分割。额外的空行可被用于(保守的(SParingly)分割相关函数组成的群(grouPSOfrelatedfUnCtiOnS)O在一组相关的单句中间可以省略空行。(例如.一组哑元(asetofdummyimpIementations)o当空行用于分割方法(method)的定义时,在class,行和第一个方法定义之间也要有一个空行。在函数中使用空行时,请谨慎的用于表示一个逻辑段落(indicatelogicalsect
7、ions).Python接受conto-L(即CL)换页符作为空格;Emacs(和一些打印工具)视这个字符为页面分割符,因此在你的文件中,可以用他们来为相关片段(SeCtiOnS)分页。2编码PythOn核心发布中的代码必须始终使用ASCIl或LatinT编码(又名ISO-8859-1)o使用ASCII的文件不必有译码COOkie(COdingcookie).Latin-1仅当注释或文档字符串涉及作者名字需要Latin1时才被使用;另外使用x转义字符是在字符串中包含非ASCII(non-ASCII)数据的首选方法。作为PEP263实现代码的测试套件的部分文件是个例外.Python2.4以后内核
8、支持Unicode了!不论什么情况使用UTF-8吧!2.1导入通常应该在单独的行中导入(ImPOrts),例如:No:importsys,osYes:importsysimportos但是这样也是可以的:fromtypesimportStringType,LiStTypeImports通常被放置在文件的顶部,仅在模块注释和文档字符串之后,在模块的全局变量和常量之前.Imports应该有顺序地成组安放。1 o标准库的导入(I叩OrtS)2 .相关的主包(majorPaCkage)的导入(即,所有的emaiI包在随后导入)3 .特定应用的导入(imports)你应该在每组导入之间放置一个空行。对于
9、内部包的导入是不推荐使用相对导入的。对所有导入都要使用包的绝对路径.从一个包含类的模块中导入类时,通常可以写成这样:fromMyCIassimportMyCIassfromfoo.baroYourCIassimportYourCIass如果这样写导致了本地名字冲突,那么就这样写importMyCIassimportfoo.baroYourCIass*即使用MyCIass.MyCIass和fooobar.YourCIass.YourCIass2.2空格(WhitespaceinExpressionsandStatements)*GUidO不喜欢在以下地方出现空格:“spam(ham1,eggs:
10、2)oAlwayswritethisas“spam(ham1,eggs:2),o紧挨着圆括号,方括号和花括号的,如:,spam(ham1,eggs:if x = 4 :要始终将它写成spam(ham1,eggs:2),oprintx,y;x,y=y,xoAlwayswritethisas”ifx=4:print x, y; x, y = y, xo紧贴在逗号,分号或冒号前的,如:if X = 4:print x , y ; x , y = y , xo 要始终将它写成if x = 4:pr i nt,y; , y - y,紧贴着函数调用的参数列表前开式括号(openparenthesis)的,
11、如“ spam(1)”.要始终将它写成“SPam(I) ”。siicing,asin:diet,key,=Iistindex,.Alwayswritethisasdiet key,=Iistindex,o紧贴在索引或切片(SliCing?下标?)开始的开式括号前的,如:Toggle123Toggle1232.3,dietkey,=Iistindex,o要始终将它写成“diet,key,二Iistindex,.o在赋值(或其它)运算符周围的用于和其它并排的一个以上的空格,如:Iinenumbersx二1V-2Iong_variabIe=3*要始终将它写成Iinenumbersx二1y-2long
12、_variabIe=3*(不要对以上任意一条和他争论Guido养成这样的风格超过20年了。)其它建议(OtherRecommendations)始终在这些二元运算符两边放置一个空格:赋值(二),比较仁二,,!二,,not).=,in,notin,is,isnot),布尔运算(and,or*按你的看法在算术运算符周围插入空格。始终保持二元运算符两边空格的一致。ToggleIinenumbers1i=i+12submitted=submitted+13x=x*2-14hypot2=x*x+y*y5c=(a+b)*(a-b)6c-(a+b)*(a-b)*不要在用于指定关键字参数或默认参数值的二号周围
13、使用空格,例如:ToggleIinenumbersdefcompIex(reaI,imag=0o0):2i=imag)returnmagic(r=reaI,*不要将多条语句写在同一行上。No:iffoo=blah:do_bIah_thing()Yes:iffoo=blah,:do_bIah_thingONo:do_oneO;do_two();do_threeOYes:do_one()do_twoOdo_three()2.4注释(Comments)*同代码不一致的注释比没注释更差。当代码修改时,始终优先更新注释!注释应该是完整的句子。如果注释是一个短语或句子,首字母应该大写,除非他是一个以小写字
14、母开头的标识符(永远不要修改标识符的大小写).如果注释很短,最好省略末尾的句号(period?结尾句末的停顿?也可以是逗号吧,)注释块通常由一个或多个由完整句子构成的段落组成,每个句子应该以句号结尾。你应该在句末,句号后使用两个空格,以便使EmaCS的断行和填充工作协调一致(译按:应该说是使这两种功能正常工作给出了文档结构的提示)。用英语书写时,断词和空格是可用的。非英语国家的PythOn程序员:请用英语书写你的注释,除非你120%的确信这些代码不会被不懂你的语言的人阅读。我就是坚持全部使用中文来注释,真正要发布脚本工具时,再想E文的;开发时每一瞬间都要用在思量中,坚决不用在E文语法,单词的回
15、忆中!ZoomQUiet约定使用统一的文档化注释格式有利于良好习惯和团队建议!一CodeCommentingRuIe2.4.1注释块(BlockComments)*注释块通常应用于跟随着一些(或者全部)代码并和这些代码有着相同的缩进层次。注释块中每行以#和一个空格开始(除非他是注释内的缩进文本).注释块内的段落以仅含单个#的行分割。注释块上下方最好有一空行包围(或上方两行下方一行,对一个新函数定义段的注释)。2.4.2行内注释(lnlineComments)*(inline?内联?翻成“行内”比较好吧)0一个行内注释是和语句在同一行的注释。行内注释应该谨慎适用.行内注释应该至少用两个空格和语句
16、分开。它们应该以#和单个空格开始.x = x+1#IncrementX*如果语意是很明了的,那么行内注释是不必要的,事实上是应该被去掉的。不要这样写:x+1IncrementXx+1Compensateforborder*但是有时,这样是有益的:x+1Compensateforborder2.5文档化(DocumentationStrings)*Conventionsforwritinggooddocumentationstrings(aok0a.docstrings)areimmortaIizedinPEP257o应该一直遵守编写好的文档字符串(又名docstrings)的约定(?实在不知道
17、怎么译)DocumentationStrings文档化字符;为配合pydoc;epydoc,DOXygen等等文档化工具的使用,类似于MOinMOin语法,约定一些字符,以便自动提取转化为有意义的文档章节等等文章元素!Zoomq大为所有公共模块,函数,类和方法编写文档字符串。文档字符串对非公开的方法不是必要的,但你应该有一个描述这个方法做什么的注释,这个注释应该在“def”这行后。*PEP257描述了好的文档字符串的约定,一定注意,多行文档字符串结尾的”应该单独成行,例如:ReturnafoobangOptionaIpIotzsaystofrobnicatethebizbazfirsto*对单
18、行的文档字符串,结尾的”在同一行也可以。实际上Python自个儿就使用文档化编码维护着所有内置对象的使用说明不信的话常试:#pythonimporttimedir(time),_doc_,_fiIe_,_name_,accept2dyear,aItzone,asctime,cIock,ctime,dayIight,gmtime,localtime,mktime,sIeep,strftime,Strptime,struct_time,time,timezone,tzname,tzset,heIp(time,time)HeIponbui11-infunctiontimeinmoduIetime:t
19、ime(ooo)time()fIoatingpointnumberReturnthecurrenttimeinsecondssincetheEpochoFractionsofasecondmaybepresentifthesystemcIockprovidesther11o2.6版本注记(VersionBookkeeping)(我觉得叫注记更好)*如果你要将RCS或CVS的杂项(crud)包含在你的源文件中,按如下做。ToggleIinenumbers1 _version_=$Revision:1.4$2 #$Source:E:/cvsrootpython_doc/pep8otxt,v$*这个
20、行应该包含在模块的文档字符串之后,所有代码之前,上下用一个空行分割。对于CVS的服务器工作标记更应该在代码段中明确出它的使用如:在文档的最开始的版权声明后应加入如下版本标记:#文件:$id$# 版本:$ReViSiOr)$这样的标记在提交给配置管理服务器后,会自动适配成为相应的字符串,如:# 文件:$ld:usspopy,V1o222004/07/2104:47:41hdExp$# 版本:$Revision:1o4$HD2.7命名约定*PythOn库的命名约定有点混乱,所以我们将永远不能使之变得完全一致不过还是有公认的命名规范的。新的模块和包(包括第三方的框架)必须符合这些标准,但对已有的库存
21、在不同风格的,保持内部的一致性是首选的。*有许多不同的命名风格。以下的有助于辨认正在使用的命名风格,独立于它们的作用。以下的命名风格是众所周知的:* b(单个小写字母)* B(单个大写字母)* 小写串如:getname* 带下划的小写串如:_getname*大写串如:GETNAME夫带下划的大写串如:_GETNAME*CaPitaliZedWOrdS(首字母大写单词串)(或CapWords,CameICase这样命名是由于它的字母错落有致的样子而来的.这有时也被当作StUdlyCaPSo如:GetName*RiixedCase(混合大小写串)(与首字母大写串不同之处在于第一个字符是小写如:ge
22、tName)*CapitaIized_Words_With_Underscores(带下划线的首字母大写串)(丑陋!)还有一种使用特别前缀的风格,用于将相关的名字分成组。这在Python中不常用,但是出于完整性要提一下。例如,os.stat()函数返回一个tuple,他的元素传统上有象StJTlOde,st_size,Stjntime等等这样的名字.X11库的所有公开函数以X开头。(在PythOn中,这个风格通常认为是不必要的,因为属性和方法名以对象作前缀,而函数名以模块名作前缀.)另外,以下用下划线作前导或结尾的特殊形式是被公认的(这些通常可以和任何习惯组合(使用?):*_singIe_le
23、ading_underscore(以一,个下划线作前导):弱的”内部使用(internaluse)”标志.0(例如,fromMimport*不会导入以下划线开头的对象)。*single_traiIing_underscore_(以一个下划线结尾):用于避免与Python关键词的冲突,例如。“TkinteroToplevel(master,CIaSSJzClassName,)”.*_doubIe_leading_underscore(双下划线):从PythOn1o4起为类私有名。*_doubIe_leading_and_traiIing_underscore_:特殊的(magic)对象或属性,存
24、在于用户控制的(IlSer-COrrtrOlled)名字空间,例如:_init_,_import_或_fiIe_o有时它们被用户定义,用于触发某个特殊行为(magicbehavior)(例如:运算符重载);有时被构造器(infrastructure)插入,以便自己使用或为了调试.因此,在未来的版本中,构造器(松散得定义为Python解释器和标准库)可能打算建立自己的魔法属性列表,用户代码通常应该限制将这种约定作为己用。欲成为构造器的一部分的用户代码可以在下滑线中结合使用短前缀,例如._bobo_magic_attr_。2.7.2说明:命名约定(Prescriptive:NamingConven
25、tions)(NamestoAvoid)*永远不要用字符I(小写字母el(就是读音,下同),0,(大写字母。h),或1(大写字母eye)作为单字符的变量名。在某些字体中,这些字符不能与数字1和0分开。当想要使用I时,用L,代替它.2.7.3.1 模块名(ModuleNames)模块应该是不含下划线的,简短的,小写的名字。因为模块名被映射到文件名,有些文件系统大小写不敏感并且截短长名字,模块名被选为相当短是重要的这在UniX上不是问题,但当代码传到MaC或WindOWS上就可能是个问题了。当一个用C或C+写的扩展模块有一个伴随的Python模块,这个Python模块提供了0一个更高层(例如,更面
26、向对象)的接口时,C/C+模块有一个前导下划线(如:_socket)Python包应该是不含下划线的,简短的,全小写的名字.2.7.3.2 类名(ClaSSNames)*几乎没有例外,类名总是使用首字母大写单词串(CaPWOrdS)的约定.2.7.3.3 异常名(ExceptionNames)*如果模块对所有情况定义了单个异常,它通常被叫做“error”或ErrOr”。似乎内建(扩展)的模块使用error(例如:oSoerrOr),而PythOn模块通常用Error(例如:xdrIiboError)o趋势似乎是倾向使用CapWords异常名。2.73.4全局变量名(GlObalVariabIe
27、Names)*(让我们希望这些变量打算只被用于模块内部)这些约定与那些用于函数的约定差不多。被设计可以通过“fromMimport来使用的o那些模块,应该在那些不想被导入的全局变量(还有内部函数和类)前加一个下划线)。2.7.3.5函数名(FUnCtiOnNames)*函数名应该为小写,可能用下划线风格单词以增加可读性。mixedCase仅被允许用于这种风格已经占优势的上下文(如:threadingopy)以便保持向后兼容。2.73.6方法名和实例变量(MethOdNamesandInstanceVariabIes)*这段大体上和函数相同:通常使用小写单词,必要时用下划线分隔增加可读性。使用一
28、个前导下划线仅用于不打算作为类的公共接口的内部方法和实例变量.Python不强制要求这样;它取决于程序员是否遵守这个约定。使用两个前导下划线以表示类私有的名字。PythOn将这些名字和类名连接在一起:如果类Foo有一个属性名为_a,它不能以Foo。_a访问。(执著的用户(AninSiStentilSer)还是可以通过FOO._Foo_a得到访问权.)通常,双前导下划线应该只用来避免与类(为可以子类化所设计)中的属性发生名字冲突。2.7.3.7继承的设计(DeSigningforinheritance)*始终要确定一个类中的方法和实例变量是否要被公开。通常,永远不要将数据变量公开,除非你实现的本
29、质上只是记录。人们总是更喜欢给类提供一个函数的接口作为替换(PythOn2。2的一些开发者在这点上做得非常漂亮)。同样,确定你的属性是否应为私有的。私有与非公有的区别在于:前者永远不会被用在一个派生类中,而后者可能会。是的,你应该在大脑中就用继承设计好了你的类。私有属性必须有两个前导下划线,无后置下划线,非公有属性必须有一个前导下划线,无后置下划线.公共属性没有前导和后置下划线,除非它们与保留字冲突,在此情况下,单个后置下划线比前置或混乱的拼写要好,例如:ClaSS优于klass。最后一点有些争议;如果相比ClaSS_你更喜欢klass,那么这只是一致性问题。3设计建议(Programming
30、Recommendations)*同象NOne之类的单值进行比较,应该永远用:is或isnot来做。当你本意是“ifXisnotNOne”时,对写成”ifx要小心例如当你测试一个默认为None的变量或参数是否被设置为其它值时。这个其它值可能是一个在布尔上下文中为假的值!*基于类的异常总是好过基于字符串的异常。模块和包应该定义它们自己的域内特定的基异常类(baseexceptioncIass),基类应该是内建的EXCePtiOn类的子类.还始终包含一个类的文档字符串.例如:ToggleIinenumbers1 cIassMessageError(Exception):2 ,BasecIassfo
31、rerrorsintheemaiIpackageo,*使用字符串方法(methods)代替字符串模块,除非必须向后兼容PythOn2o0以前的版本。字符串方法总是非常快,而且和UniCOde字符串共用同样的API(应用程序接口)夫在检查前缀或后缀时避免对字符串进行切片。用StartSWith()和endswith()代替,因为它们是明确的并且错误更少。例如:No:iffoo:3=bar,:Yes:iffoooStartswith(,bar):* 例外是如果你的代码必须工作在PythOnK5o2(但是我们希望它不会发生!)。* 对象类型的比较应该始终用isinstanceO代替直接比较类型.例如
32、:No:iftype(obj)istype(1):Yes:ifisinstance(obj,int):* 检查一个对象是否是字符串时,紧记它也可能是UniCOde字符串!在PythOn2。3,Str和UniCode有公共的基类,basestring,所以你可以这样做:ToggleIinenumbers1 ifisinstance(obj,basestring):*在PythOn2o2类型模块为此定义了StringTyPeS类型,例如:ToggleIinenumbers1 fromtypesimportStringTypes2 ifisinstance(obj,StringTypes):*在Py
33、thOn2.0和2。1,你应该这样做:ToggleIinenumbers1 fromtypesimportStringType,UnicodeType2 ifisinstance(obj,StringType)orisinstance(obj,UnicodeType):*对序列,(字符串(Strings),列表(IiStS),元组(tuples),使用空列表是false这个事实,因此ifnotseq,或“ifseq比ifIen(Seq)或ifnotIen(seq),好。*书写字符串文字时不要依赖于有意义的后置空格。这种后置空格在视觉上是不可辨别的,并且有些编辑器(特别是近来,reindent。py)会将它们修整掉.*不要用=来比较布尔型的值以确定是TrUe或FalSe(布尔型是Pythn2。3中新增的)No:ifgreeting=True:Yes:ifgreeting:No:ifgreeting=True:Yes:ifgreeting: