活動地址:CSDN21天學習挑戰賽
想要寫好python代碼,必須了解python相關編碼規范,本文主要分享相應的python編碼規范。
如果Python源碼文件沒有聲明編碼格式,Python解釋器會默認使用ASCII編碼。但出現非ASCII編碼的字符,Python解釋器就會報錯,因此非 ASCII 字符的字符串,請需添加u前綴。
# -- coding: utf-8 解決編碼問題--
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
不要在行尾加分號,也不要用分號將兩條命令放在同一行。
每行不超過80個字符,不要使用反斜槓連接行(圓括號、方括號或花括號以內的表達式允許分成多個物理行)。
特殊情況除外:
if a==0:
print("hello") # 縮進4個空白占位
else: # 與if對齊
print("word") # 縮進4個空白占位
或者
# 4 個空格縮進,第一行不需要
foo = long_fn(
var_0, var_1, var_2,
var_3)
Python中有三種形式的注釋:行注釋、塊注釋、文檔注釋
行注釋是與代碼語句同行的注釋,注釋和代碼至少要有兩個空格分隔,注釋由#和一個空格開始。
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)
塊注釋通常適用於跟隨它們的某些(或全部)代碼,並縮進到與代碼相同的級別。塊注釋的每一行開頭使用一個 # 和一個空格(除非塊注釋內部縮進文本),塊注釋內部的段落通常只有一個 # 的空行分隔。
def Fn(param1,parame2):
""" 描述函數要做的事情 :param parameter1: 參數一描述(類型、用途等) :param parameter2: 參數二描述 :return: 返回值描述 """
要為所有的公共模塊,函數,類和方法編寫文檔說明。非公共的方法沒有必要,但是應該有一個描述方法具體作用的注釋。這個注釋應該在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個空格,塊注釋後面最好多留幾行空白再寫代碼。
- 當代碼更改時,優先更新對應的注釋。
- 如果一個注釋是一個短語或者句子,它的第一個單詞應該大寫,除非它是以小寫字母開頭的標識符(永遠不要改變標識符的大小寫!)。
- 如果注釋很短,結尾的句號可以省略。塊注釋一般由完整句子的一個或多個段落組成,並且每句話結束有個句號。
- 在句尾結束的時候應該使用兩個空格。
頂層函數和類定義,前後用兩個空行隔開。編碼格式聲明、模塊導入、常量和全局變量聲明、頂級定義和執行代碼之間空兩行。類裡面方法定義用一個空行隔開。在函數或方法內部,可以在必要的地方空一行以增強節奏感,但應避免連續空行。
class Class1:
pass
class Class2:
def fn_1(self):
pass
def fn_02(self):
pass
# 標准范例
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)
# 模塊名命名
# 模塊盡量使用小寫命名,首字母保持小寫,盡量不要用下劃線(除非多個單詞,且數量不多的情況)
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.') # 在同一個文件中,保持使用字符串引號的一致性。在字符串內可以使用另外一種引號,以避免在字符串中使用。
導入應該放在文件頂部,位於模塊注釋和文檔字符串之後,模塊全局變量和常量之前。導入應該按照從最通用到最不通用的順序分組:標准庫導入、第三方庫導入、應用程序指定導入,分組之間空一行。盡量保持模塊名簡單,以無需分開單詞最佳(不推薦在兩個單詞之間使用下劃線)。
import os # 模塊名稱要短,使用小寫,並避免使用特殊符號, 比如點和問號。
import numpy # 每個導入應該獨占一行。
import sys
from types import StringType, ListType
def main():
... # 主功能應該放在一個main()函數中。
if __name__ == '__main__': # 代碼應該在執行主程序前總是檢查 if __name__ == '__main__', 這樣當模塊被導入時主程序就不會被執行。
main()
__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 $
模塊 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
是一個 將模塊名稱(module_name
)映射到已加載的模塊(modules
) 的字典。可用來強制重新加載modules
。Python一啟動,它將被加載在內存中。
import sys
print(sys.modules) # 打印,查看該字典具體內容。
所有的模塊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
只關心相對自己當前目錄的模塊位置就好。不能在包(package
)的內部直接執行(會報錯)。不管根節點在哪兒,包內的模塊相對位置都是正確的。
# b1.py代碼
# from . import b2 # 這種導入方式會報錯。
import b2 # 正確
b2.print_b2()
# b2.py代碼
def print_b2():
print('b2')
# 運行b1.py,打印:b2。
re 庫
是 Python 中處理正則表達式的標准庫,本篇博客介紹 re 庫的同時,簡單介紹一下網絡爬蟲初階正則表達式語法。
re 庫主要函數如下:
基礎函數:compile
;
功能函數:search
、match
、findall
、split
、finditer
、sub
。
# 不使用原生字符串的正則表達式 "\\\\"
# 使用原生字符串的正則表達式 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(全名:JavaScript Object Notation 對象表示法)是一種輕量級的文本數據交換格式,JSON的數據格式其實就是python裡面的字典格式,裡面可以包含方括號括起來的數組,也就是python裡面的列表。
{
key1:value1, key2:value2,} # 鍵值對形式(用冒號分開),對間用逗號連接
作用: 使用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的都是和文件相關的
# 新建一個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"
}
}
# 新建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>