程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

「Python入門」Python代碼規范(風格)

編輯:Python


活動地址:CSDN21天學習挑戰賽

文章目錄

  • 前言
  • 一、編碼規范
  • 二、分號
  • 三、行的最大長度
  • 四、 縮進規則
  • 五、Python注釋
    • 5.1 行注釋
    • 5.2 塊注釋
    • 5.3 文檔注釋
  • 六、 Python空行
  • 七、 Python空格的使用規范
  • 八、 Python命名規范
  • 九、引號用法規則
  • 十、Python模塊導入規則
  • 十一、 Main
  • 十二、Python函數設計規范
  • 十三、Python版本注記
  • 十四、Python模塊、包
  • 十五、 sys.modules
  • 十六、 Python相對與絕對導入
    • 16.1 絕對導入
    • 16.2 Python相對導入
  • 十七、 Python正則表達式(網絡爬蟲)
  • 十八、 re 庫基本用法
  • 十九、json標准庫總結
    • 19.1 JSON是什麼
    • 19.2 JSON語法格式
    • 19.3 json模塊
    • 19.4 XML文件轉為JSON文件
    • 19.5 JSON文件轉換為XML文件


前言

想要寫好python代碼,必須了解python相關編碼規范,本文主要分享相應的python編碼規范。


一、編碼規范

如果Python源碼文件沒有聲明編碼格式,Python解釋器會默認使用ASCII編碼。但出現非ASCII編碼的字符,Python解釋器就會報錯,因此非 ASCII 字符的字符串,請需添加u前綴。

# -- coding: utf-8 解決編碼問題--
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

二、分號

不要在行尾加分號,也不要用分號將兩條命令放在同一行。

三、行的最大長度

每行不超過80個字符,不要使用反斜槓連接行(圓括號、方括號或花括號以內的表達式允許分成多個物理行)。

特殊情況除外:

  1. 長的導入模塊語句
  2. 注釋裡的URL

四、 縮進規則

  • Python 采用代碼縮進和冒號( : )來區分代碼塊之間的層次。
  • 在 Python中,對於類定義、函數定義、流程控制語句、異常處理語句等,行尾的冒號和下一行的縮進,表示下一個代碼塊的開始,而縮進的結束則表示此代碼塊的結束。
  • Python 中實現對代碼的縮進,可以使用空格或者 Tab 鍵實現。但無論是手動敲空格,還是使用 Tab 鍵,通常情況下都是采用 4個空格長度作為一個縮進量(默認情況下,一個 Tab 鍵就表示 4 個空格)。
  • 對於 Python縮進規則,初學者可以這樣理解,Python 要求屬於同一作用域中的各行代碼,它們的縮進量必須一致,但具體縮進量為多少,並不做硬性規定。
if a==0:
print("hello") # 縮進4個空白占位
else: # 與if對齊
print("word") # 縮進4個空白占位
或者
# 4 個空格縮進,第一行不需要
foo = long_fn(
var_0, var_1, var_2,
var_3)

五、Python注釋

Python中有三種形式的注釋:行注釋塊注釋文檔注釋

5.1 行注釋

行注釋是與代碼語句同行的注釋,注釋和代碼至少要有兩個空格分隔,注釋由#和一個空格開始。

a = input()
b = input()
c = a / 2 # c是a的一半
# 循環,條件為c*b/a 小於a
while (c * b / (a + 1) < a):
c = 0.5 * b + a / 2 # 重新計算c值
print(c)

5.2 塊注釋

塊注釋通常適用於跟隨它們的某些(或全部)代碼,並縮進到與代碼相同的級別。塊注釋的每一行開頭使用一個 # 和一個空格(除非塊注釋內部縮進文本),塊注釋內部的段落通常只有一個 # 的空行分隔。

def Fn(param1,parame2):
""" 描述函數要做的事情 :param parameter1: 參數一描述(類型、用途等) :param parameter2: 參數二描述 :return: 返回值描述 """

5.3 文檔注釋

要為所有的公共模塊,函數,類和方法編寫文檔說明。非公共的方法沒有必要,但是應該有一個描述方法具體作用的注釋。這個注釋應該在def那一行之後。多行文檔注釋使用的結尾三引號應該是自成一行。

class ClassFn(object):
"""Summary of class here.
""" def __init__(self, likes_spam=False): """Inits ClassFn with blah.""" self.likes_spam = likes_spam self.eggs = 0 def public_method(self): """Performs operation blah."""
  • Python中使用 # 進行注釋,# 號後面要空一格。
  • 最需要寫注釋的是代碼中那些技巧性的部分:對於復雜的操作,應該在其操作開始前寫上若干行注釋.;對於不是一目了然的代碼,應在其行尾添加注釋。
  • 為了提高可讀性,注釋和代碼隔開一定的距離,注釋應該至少離開代碼2個空格,塊注釋後面最好多留幾行空白再寫代碼。
  • 當代碼更改時,優先更新對應的注釋。
  • 如果一個注釋是一個短語或者句子,它的第一個單詞應該大寫,除非它是以小寫字母開頭的標識符(永遠不要改變標識符的大小寫!)。
  • 如果注釋很短,結尾的句號可以省略。塊注釋一般由完整句子的一個或多個段落組成,並且每句話結束有個句號。
  • 在句尾結束的時候應該使用兩個空格。

六、 Python空行

頂層函數和類定義,前後用兩個空行隔開。編碼格式聲明、模塊導入、常量和全局變量聲明、頂級定義和執行代碼之間空兩行。類裡面方法定義用一個空行隔開。在函數或方法內部,可以在必要的地方空一行以增強節奏感,但應避免連續空行。

class Class1:
pass
class Class2:
def fn_1(self):
pass
def fn_02(self):
pass

七、 Python空格的使用規范

  • 在二元運算符兩邊各空一格,比如賦值(=)、比較(==, <, >, !=, <>, <=, >=, in, not in, is, is not), 布爾(and, or, not),算術操作符兩邊的空格可靈活使用,但兩側務必要保持一致
  • 不要在逗號、分號、冒號前面加空格,但應該在它們後面加(除非在行尾)
  • 函數的參數列表中,逗號之後要有空格
  • 函數的參數列表中,默認值等號兩邊不要添加空格
  • 左括號之後,右括號之前不要加添加空格
  • 參數列表, 索引或切片的左括號前不應加空格
  • 當’='用於指示關鍵字參數或默認參數值時,不要在其兩側使用空格
# 標准范例
spam(ham[1], {
eggs: 2}, [])
if x == 4:
print x, y
x, y = y, x
dict['key'] = list[index]
def complex(real, imag=0.0): return magic(r=real, i=imag)

八、 Python命名規范

# 模塊名命名
# 模塊盡量使用小寫命名,首字母保持小寫,盡量不要用下劃線(除非多個單詞,且數量不多的情況)
import decoder
import html_parser
# 變量命名
# 變量名盡量小寫, 如有多個單詞,用下劃線隔開。
count = 0
this_count = 1
# 常量或者全局變量命名
# 全部大寫,如有多個單詞,用下劃線隔開,全⼤寫+下劃線式駝峰
MAX_COUNT = 99
# 函數命名
# 函數名應該小寫,如有多個單詞,用下劃線隔開。 大小寫混合僅在為了兼容原來主要以大小寫混合風格的情況下使用,保持向後兼容。 私有函數在函數前加一個下劃線_。
def run():
pass
def run_with_env():
pass
class Person():
def _private_func():
pass
# 類命名
# 類名使用駝峰(CamelCase)命名風格,首字母大寫,私有類可用一個下劃線開頭。
# 在接口被文檔化並且主要被用於調用的情況下,可以使用函數的命名風格代替。
# 對於內置的變量命名有一個單獨的約定:大部分內置變量是單個單詞(或者兩個單詞連接在一起),首字母大寫的命名法只用於異常名或者內部的常量。
class Farm():
pass
class AnimalFarm(Farm):
pass
class _PrivateFarm(Farm):
pass
# python1.py 范例代碼
def func(a=1):
b = 2
print(locals()) # 打印當前函數(方法)的局部命名空間
'''
locs = locals() # 只讀,不可寫。將報錯!
locs['c'] = 3
print(c)
'''
return a+b
func()
glos = globals()
glos['d'] = 4
print(d)
print(globals()) # 打印當前模塊 python1.py的全局命名空間(可寫)

注:

  • 不要中英文混編
  • 不要有a、b、c這種沒有意義的命名
  • 不要怕名字長就隨便縮寫,比如good_info 縮寫成gi
  • 不要用大小寫區分變量類型,比如a是int類型,A是String類型
  • 不要使用容易引起混淆的變量名
  • bool變量⼀般加上前綴 is_ 如:is_success
  • 變量名不要用系統關鍵字,如 dir type str等等
  • 用下畫線作前導(_simple_done)或結尾(simple_done_)的特殊形式是被公認的

九、引號用法規則

One('hello world?')
Tow("my site is vitian.vip") # 單引號和雙引號字符串是相同的。
Three('"hell!" vitian.') # 在同一個文件中,保持使用字符串引號的一致性。在字符串內可以使用另外一種引號,以避免在字符串中使用。

十、Python模塊導入規則

導入應該放在文件頂部,位於模塊注釋和文檔字符串之後,模塊全局變量和常量之前。導入應該按照從最通用到最不通用的順序分組:標准庫導入、第三方庫導入、應用程序指定導入,分組之間空一行。盡量保持模塊名簡單,以無需分開單詞最佳(不推薦在兩個單詞之間使用下劃線)。

import os # 模塊名稱要短,使用小寫,並避免使用特殊符號, 比如點和問號。
import numpy # 每個導入應該獨占一行。
import sys
from types import StringType, ListType

十一、 Main

def main():
... # 主功能應該放在一個main()函數中。
if __name__ == '__main__': # 代碼應該在執行主程序前總是檢查 if __name__ == '__main__', 這樣當模塊被導入時主程序就不會被執行。
main()

十二、Python函數設計規范

  • 函數設計的主要目標就是最大化代碼重用和最小化代碼冗余。精心設計的函數不僅可以提高程序的健壯性,還可以增強可讀性、減少維護成本。
  • 函數設計要盡量短小,嵌套層次不宜過深。 所謂短小, 就是盡量避免過長函數, 因為這樣不需要上下拉動滾動條就能獲得整體感觀, 而不是來回翻動屏幕去尋找某個變量或者某條邏輯判斷等。 函數中需要用到 if、 elif、 while 、 for 等循環語句的地方,盡量不要嵌套過深,最好能控制在3層以內。不然有時候為了弄清楚哪段代碼屬於內部嵌套, 哪段屬於中間層次的嵌套, 哪段屬於更外一層的嵌套所花費的時間比讀代碼細節所用時間更多。
  • 盡可能通過參數接受輸入,以及通過return產生輸出以保證函數的獨立性。
  • 盡量減少使用全局變量進行函數間通信。
  • 不要在函數中直接修改可變類型的參數。
  • 函數申明應該做到合理、 簡單、 易於使用。 除了函數名能夠正確反映其大體功能外, 參數的設計也應該簡潔明了, 參數個數不宜太多。 參數太多帶來的弊端是: 調用者需要花費更多的時間去理解每個參數的意思,測試的時候測試用例編寫的難度也會加大。
  • 函數參數設計應該考慮向下兼容。

十三、Python版本注記

__version__ = "$Revision: 1.4 $"
# $Source: E:/cvsroot/python_doc/pep8.txt,v $ 將 RCS 或 CVS 的雜項包含在你的源文件中
# 對於 CVS 的服務器工作標記更應該在代碼段中明確出它的使用說明,如在文檔最開始的版權聲明後應加入如下版本標記:
# 文件:$id$
# 版本:$Revision$
# 這樣的標記在提交給配置管理服務器後,會自動適配成為相應的字符串
# 文件:$Id: ussp.py,v 1.22 2004/07/21 04:47:41 hd Exp $
# 版本:$Revision: 1.4 $

十四、Python模塊、包

模塊 module: 一般情況下,是一個以.py為後綴的文件。其他可作為module的文件類型還有".pyo"、“.pyc”、“.pyd”、“.so”、“.dll”。
module 可看作一個工具類,可共用或者隱藏代碼細節,將相關代碼放置在一個module以便讓代碼更好用、易懂,讓coder重點放在高層邏輯上。
module能定義函數、類、變量,也能包含可執行的代碼。
module來源有3種:①Python內置的模塊(標准庫);②第三方模塊;③自定義模塊。

當一個文件夾下有 __init__.py時,意為該文件夾是一個包(package),其下的多個模塊(module)構成一個整體,而這些模塊(module)都可通過同一個包(package)導入其他代碼中。

__init__.py文件用於組織包(package),方便管理各個模塊之間的引用、控制著包的導入行為。在 __init__.py導入我們需要的模塊,以便避免逐一導入、方便使用。

十五、 sys.modules

sys.modules 是一個 將模塊名稱(module_name)映射到已加載的模塊(modules) 的字典。可用來強制重新加載modules。Python一啟動,它將被加載在內存中。

import sys
print(sys.modules) # 打印,查看該字典具體內容。

十六、 Python相對與絕對導入

16.1 絕對導入

所有的模塊import都從“根節點”開始。根節點的位置由sys.path中的路徑決定,項目的根目錄一般自動在sys.path中。

import sys,os
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # 存放c.py所在的絕對路徑
sys.path.append(BASE_DIR)
from B.B1 import b1 # 導入B包中子包B1中的模塊b1

16.2 Python相對導入

只關心相對自己當前目錄的模塊位置就好。不能在包(package)的內部直接執行(會報錯)。不管根節點在哪兒,包內的模塊相對位置都是正確的。

# b1.py代碼
# from . import b2 # 這種導入方式會報錯。
import b2 # 正確
b2.print_b2()
# b2.py代碼
def print_b2():
print('b2')
# 運行b1.py,打印:b2。

十七、 Python正則表達式(網絡爬蟲)

re 庫是 Python 中處理正則表達式的標准庫,本篇博客介紹 re 庫的同時,簡單介紹一下網絡爬蟲初階正則表達式語法。

操作符說明例子.任何單個字符,極少不能匹配[]字符集,對單個字符給出取值范圍[abc] 表示匹配 a、b、c,[a-z] 表示 a 到 z 單個字符[^]非字符集,對單個字符給出排除范圍[^abc] 表示匹配 非 a、非 b、非 c 的單個字符*前一個字符 0 次或無限次擴展abc* 表示 ab、abc、abcc、abccc 等+前一個字符 1 次或無限次擴展abc+ 表示 abc、abcc、abccc 等?前一個字符 0 次或 1 次abc? 表示 ab、abc丨左右表達式任意一個abc丨def 表示 abc 或者 def{m}擴展前 1 個字符 m 次ab{2}c,表示 abbc{m,n}擴展前 1 個字符 m 到 n 次ab{1,2}c,表示 abc、abbc^匹配字符串開頭^abc 表示$匹配字符串結尾abc$ 表示()分組標記,內部僅能使用操作符(abc) 表示 abc,(a\d數字,等價於 [0-9]\w字符,等價於 [A-Za-z0-9]

十八、 re 庫基本用法

re 庫主要函數如下:
基礎函數:compile
功能函數:searchmatchfindallsplitfinditersub

# 不使用原生字符串的正則表達式 "\\\\"
# 使用原生字符串的正則表達式 r"\\"
vitian_str='D:\python' # 如果希望字符串中 ' 可以正常運行,需要加上轉移字符 \
print(vitian_str) # => 輸出結果:
D:
python
vitian_str= r'D:\python' # \n 被解析成了換行,如果想要屏蔽這種現象,使用 r
print(vitian_str) # => D:\python
import re
vitian_str='你好我是vitian,歡迎來到我的博客'
pattern = r'vitian'
# search 范例
ret = re.search(pattern,vitian_str)
if ret:
print(ret.group(0)) # => vitian
# print(ret) # => <re.Match object; sapn=(4,10), match='vitian'>
# re.match 范例
ret = re.match(pattern,vitian_str)
if ret:
print(ret.group(0)) # => vitian
# re.match 和 re.search 方法都是一次最多返回一個匹配對象,如果希望返回多個值,可以通過在 pattern 裡加括號構造匹配組返回多個字符串。
# re.findall 函數范例
# 該函數用於搜索字符串,以列表格式返回全部匹配到的字符串
ret = re.findall(pattern,vitian_str) # findall 范例
if ret:
print(ret.group(0)) # => vitian
# re.split 函數范例
# re.split(pattern, string, maxsplit=0, flags=0)
# 函數進行分割的時候,如果正則表達式匹配到的字符恰好在字符串開頭或者結尾,返回分割後的字符串列表首尾都多了空格,需要手動去除
import re
vitian_str='你好1我是vitian1,1歡迎來到我的博客1'
pattern = r'\d'
ret = re.split(pattern, vitian_str)
print(ret) # => ['','你好','我是vitian',',','歡迎來到我的博客','']
# re.finditer 函數
# re.finditer(pattern,string,flags=0)
# 搜索字符串,並返回一個匹配結果的迭代器,每個迭代元素都是 match 對象。
# re.sub 函數范例
# re.sub(pattern,repl,string,count=0,flags=0) # 在一個字符串中替換被正則表達式匹配到的字符串,返回替換後的字符串 repl 參數是替換匹配字符串的字符串,count 參數是匹配的最大替換次數。
import re
vitian_str='你好我是vitian,歡迎來到我的博客'
pattern = r'vitian'
ret = re.sub(pattern, "小王子", my_str)
print(ret) # => 你好我是小王子,歡迎來到我的博客

十九、json標准庫總結

JSON(全名:JavaScript Object Notation 對象表示法)是一種輕量級的文本數據交換格式,JSON的數據格式其實就是python裡面的字典格式,裡面可以包含方括號括起來的數組,也就是python裡面的列表。

19.1 JSON是什麼

  • JSON獨立於語言
  • JSON具有自我描述性,更易理解
  • JSON 比 XML 更小、更快,更易解析
  • 爬蟲經常經常會獲取接口數據,接口數據就是JSON格式

19.2 JSON語法格式

{
key1:value1, key2:value2,} # 鍵值對形式(用冒號分開),對間用逗號連接

19.3 json模塊

作用: 使用JSON字符串生成python對象(load);
數據類型轉換: 將數據從Python轉換到json格式;
使用方法:

json.dumps(obj) # 將python數據類型轉換為json格式的字符串。
json.dump(obj, fp) # 將python數據類型轉換並保存到son格式的文件內。
json.loads(s) # 將json格式的字符串轉換為python的類型。
json.load(fp) # 從json格式的文件中讀取數據並轉換為python的類型。

區別:
不管是dump還是load,帶s的都是和字符串相關的,不帶s的都是和文件相關的

19.4 XML文件轉為JSON文件

# 新建一個python1.xml文件:
<note date="23/04/2022">
<to>anna</to>
<from>vitian</from>
<msg>love</msg>
</note>
# 轉換代碼實現
import jsonimport xmltodictdef xml_to_json(xml_str):
"""parse是的xml解析器,參數需要
:param xml_str: xml字符串
:return: json字符串
"""
xml_parse = xmltodict.parse(xml_str)
# json庫dumps()是將dict轉化成json格式,loads()是將json轉化成dict格式。
# dumps()方法的ident=1,格式化json
json_str = json.dumps(xml_parse, indent=1)
return json_str
XML_PATH = './python1.xml' # xml文件的路徑with open(XML_PATH, 'r') as f:
xmlfile = f.read()
with open(XML_PATH[:-3] + 'json', 'w') as newfile:
newfile.write(xml_to_json(xmlfile))
# => 輸出結果
{

"note": {

"@date": "20220801",
"to": "anna",
"from": "vitian",
"msg": "love"
}
}

19.5 JSON文件轉換為XML文件

# 新建python2.json文件:
{

"person": {

"national": {

"name": "chinese",
},
"info": {

"sex": "man",
"name": "vitian"
},
}}
# 轉換代碼實現:
import xmltodictimport jsondef json_to_xml(python_dict):
"""xmltodict庫的unparse()json轉xml
:param python_dict: python的字典對象
:return: xml字符串
"""
xml_str = xmltodict.unparse(python_dict)
return xml_str
JSON_PATH = './python2.json' # json文件的路徑with open(JSON_PATH, 'r') as f:
jsonfile = f.read()
python_dict = json.loads(jsonfile) # 將json字符串轉換為python字典對象
with open(JSON_PATH[:-4] + 'xml', 'w') as newfile:
newfile.write(json_to_xml(python_dict))
# => 輸出結果
<?xml version="1.0" encoding="utf-8"?>
<person>
<national>
<name>chinese</name>
</national>
<info>
<sex>mane<sex>
<name>vitian<name>
</info>
</person>

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved