本文介紹了python中實用的一些語法和函數 持續更新
代碼較長 1215行 建議保存源碼 遇到有困惑的時候 在代碼中Ctrl+F尋找答案
Gitee源碼
Github源碼
目錄:
版本查看
pip 在終端使用(win+r cmd)
清華源鏡像安裝庫
編輯器默認編碼格式設置
打印與格式化輸出
數字格式化
% 格式運算符
string模塊
str
* 和 ** 用法
*args **kwargs
隨機
排列組合
連接詞
列表全為False 全為True 判斷
程序中斷
運算符
運算函數
運算模塊
迭代器
布爾值
布爾值等效
范圍
全局變量
異常處理
比較大小
列表
排序
字典
元組 unmodifiable
集合 可用於去重復元素 但會打亂順序
函數
壓縮迭代器 一一對應 取最短的iter
時間
time模塊
datetime模塊
dateutil模塊 用於datetime時間處理
calendar模塊 日歷
復制 拷貝區別
代碼優化
讀寫文件
os模塊
fnmatch模塊 主要用於文件匹配 目錄匹配 正則表達的簡化模塊
glob模塊 主要用於文件匹配
類
collections模塊 工具集合
openpyxl模塊 excel表格處理
from pyperclip import copy,paste訪問剪貼板
sys模塊
import re正則表達
pyInstaller python打包 .exe程序
cx_freeze另一種打包模塊
完整代碼和注釋如下
# -*- coding: utf-8 -*-
# Version: Python 3.9.5
# Author: TRIX
# Use:大部分不熟悉的內容都能在這里找得到解決方法
# -*-coding:utf8 -*-
#聲明python用utf-8編碼py文件
#!/usr/bin/python3
#只對 Linux/Unix 用戶適用 用來指定本腳本用什么解釋器來執行
#版本查看
cmd輸入 python --version
#python 版本更新 https://www.cnblogs.com/huny/p/13911721.html
#pip 在終端使用(win+r cmd)
pip --version#查看pip版本
#一串代碼更改pip安裝默認源 cmd (已設置)
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
#清華源鏡像安裝庫
pip install package -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip unistall package
pip list#查看安裝的所有模塊
#庫遷移 cmd
pip freeze > python_module_requirement.txt
#導出python安裝的庫的名字和版本
pip install -r python_module_requirement.txt #安裝所有庫
#pip更新
#C:\users\trix\appdata\local\programs\python\python39\python.exe -m pip install --upgrade pip
#pip手動安裝
#去https://www.lfd.uci.edu/~gohlke/pythonlibs/#packagename 下載對應的模塊 packagename是包名
#模塊版本 -cp39-win_amd64.whl
#編輯器默認編碼格式設置
#python 3 默認使用utf-8編碼
#Pycharm 設置步驟
#進入 file > Settings 在輸入框搜索 encoding
#找到 Editor > File encodings 將 IDE Encoding 和 Project Encoding 設置為utf-8
if __name__ == '__main__':#只有本程序運行的時候 if內的語句才會執行 當作為模塊導入的時候 不執行if內語句
#打印與格式化輸出
print(var)
print(var, end=str)
print(r'str')#不轉義字符
import pprint
pprint.pprint(var)#方便閱讀的打印模式
pprint.pformat(obj)#返回方便閱讀的對象
print('*{index:formatize}'.format(*arg)) #format可以接受不限個參數 位置可以不按順序 推薦使用format而不是%
"{} {}".format("hello", "world") # 不設置指定位置 按默認順序
>>>'hello world'
"{0} {1}".format("hello", "world") # 設置指定位置
>>>'hello world'
"{1} {0} {1}".format("hello", "world") # 用索引
>>>'world hello world'
print("網站名 {name}, 地址 {url}".format(name="菜鳥教程", url="www.runoob.com"))#用參數
site={"name": "菜鳥教程", "url": "www.runoob.com"}
print("網站名 {name}, 地址 {url}".format(**site))#用字典
my_list=['菜鳥教程', 'www.runoob.com']
print("網站名 {0[0]}, 地址 {0[1]}".format(my_list)) #用列表 "0" 是必須的
class AssignValue():
def __init__(self, value):
self.value=value
my_value=AssignValue(6)
print('value 為: {0.value}'.format(my_value)) #用類 "0" 是可選的
#數字格式化
輸入 格式 輸出 描述
math.pi {:.2f} 3.14 #保留小數點后兩位
math.pi {:+.2f} +3.14 #帶符號保留小數點后兩位
-1 {:+.2f} -1.00 #帶符號保留小數點后兩位
2.71828 {:.0f} 3 #不帶小數
5 {:0>2d} 05 #數字補零 (填充左邊, 寬度為2)
5 {:>3d} 5 #空格填充 (填充左邊, 寬度為3)
5 {:x<4d} 5xxx #數字補x (填充右邊, 寬度為4)
10 {:x<4d} 10xx #數字補x (填充右邊, 寬度為4)
1000000 {:,} 1,000,000 #以逗號分隔的數字格式
0.25 {:.2%} 25.00% #百分比格式 保留小數點后兩位
1000000 {:.2e} 1.00e+06 #指數記法 保留小數點后兩位
13 {:>10d} 13 #右對齊 (默認, 寬度為10)
13 {:<10d} 13 #左對齊 (寬度為10)
13 {:^10d} 13 #中間對齊 (寬度為10)
11 '{:b}' 1011 #進制轉換
11 '{:d}' 11 #十進制
11 '{:o}' 13 #八進制
11 '{:x}' b #十六進制
11 '{:#x}' 0xb #另一種十六進制
11 '{:#X}' 0XB #另一種十六進制大寫
runoob "{}{{}}" runoob{} #輸出{和}
print("*%format" %(*var))#% 格式運算符
%s #格式化字符串
%d #格式化整數
%f #格式化浮點數字 可指定小數點后的精度
%e #用科學計數法格式化浮點數
%c #格式化字符及其ASCII碼
%u #格式化無符號整型
%o #格式化無符號八進制數
%x #格式化無符號十六進制數
%X #格式化無符號十六進制數 大寫
%E #作用同%e 用科學計數法格式化浮點數 大寫
%g #%f和%e的簡寫
%G #%f 和 %E 的簡寫
%p #用十六進制數格式化變量的地址
* #定義寬度或者小數點精度
- #用做左對齊
+ #在正數前面顯示加號
<sp>#在正數前面顯示空格
# #在八進制數前面顯示零('0') 在十六進制前面顯示'0x'或者'0X'(取決於用的是'x'還是'X')
0 #顯示的數字前面填充'0'而不是默認的空格
% '%%'輸出一個單一的'%'
%y #兩位數的年份表示(00-99)
%Y #四位數的年份表示(000-9999)
%m #月份(01-12)
%d #月內中的一天(0-31)
%H #24小時制小時數(0-23)
%I #12小時制小時數(01-12)
%M #分鍾數(00=59)
%S #秒(00-59)
%a #本地簡化星期名稱
%A #本地完整星期名稱
%b #本地簡化的月份名稱
%B #本地完整的月份名稱
%c #本地相應的日期表示和時間表示
%j #年內的一天(001-366)
%p #本地A.M.或P.M.的等價符
%U #一年中的星期數(00-53)星期天為星期的開始
%w #星期(0-6) 星期天為星期的開始
%W #一年中的星期數(00-53)星期一為星期的開始
%x #本地相應的日期表示
%X #本地相應的時間表示
%Z #當前時區的名稱
(var) #映射變量(字典參數)
m.n. #m 是顯示的最小總寬度,n 是小數點后的位數(如果可用的話)
print("nHex=%x,nDec=%d,nOct=%o" %(0xFF,0xFF,0xFF))
>>>nHex=ff,nDec=255,nOct=377
print('%10.3f' % math.pi) #字段寬10 四舍五入三位小數3 默認右對齊
>>> 3.142
print('%010.3f' % math.pi) #用0填充空白 字段寬10 四舍五入三位小數3
>>>000003.142
print('%-10.3f' % math.pi) #左對齊
>>>3.142
print('%+f' % math.pi) #顯示正負號
>>>+3.141593
#string
import string
string.ascii_letters#獲取所有ascii碼中字母字符的字符串(包含大寫和小寫)
string.ascii_uppercase#獲取所有ascii碼中的大寫英文字母
string.ascii_lowercase#獲取所有ascii碼中的小寫英文字母
string.digits#獲取所有的10進制數字字符
string.octdigits#獲取所有的8進制數字字符
string.hexdigits#獲取所有16進制的數字字符
string.printable#獲取所有可以打印的字符
string.whitespace#獲取所有空白字符
string.punctuation#獲取所有的標點符號
#ASCII 美國標准信息交換代碼 定制了128個常用字符 主要是英文 數字 標點符號及鍵盤中其他按鍵對應的整數值
#A~Z 65~90
#a~z 97~122
#0~9 48~57
str=chr(index)#轉換字符索引為字符 自動識別屬於哪種編碼
ascii=ord(str)#轉換字符為字符索引 自動識別屬於哪種編碼
#str
trans_dict=str.maketrans(orgin_strs,sub_strs)#制作翻譯表 將 orgin_strs 中的每一個字符 替換成 sub_strs 中對應索引的字符 長度必須相同 返回一個ASCII或utf-8字符索引替換前后一一對應的字典
transed_str=str.translate(trans_dict)#用trans_dict替換str的所有字符
str=repr(var_name)#返回"var_name"
print(repr(s)) >>> '1 2\t 3\n 4'
class=eval(class_str)#計算字符中的表達式 或 返回字符表示的類
c=eval('pow(2,3)')#pow(x,y)返回x^y
>>>c=8
a=eval("{1:'xx',2:'yy'}")
>>> a={1:'xx',2:'yy'}
exec(str_expression)#執行字符串中的語句
execfile(filename)#執行filename文件
str.lower()
str.upper()
str.title()
str.capitalize()#only title the first word
str.swapcase()#swap lower and upper
str.center(width,str_used)#str居左居右居中 用str_used填充
str.ljust(width,str_used)
str.rjust(width,str_used)
numstr.zfill(width,default=0)#填充0占位
str.isdecimal()#判斷給定字符串是否全為數字
str.isalpha()#判斷給定的字符串是否全為字母
str.isalnum()#判斷給定的字符串是否只含有數字與字母
str.isupper()#判斷給定的字符串是否全為大寫
str.islower()#判斷給定的字符串是否全為小寫
str.istitle()#判斷給定的字符串是否符合title()
str.isspace()#判斷給定的字符串是否為空白符(空格 換行 制表符)
str.isprintable()#判斷給定的字符串是否為可打印字符(只有空格可以 換行 制表符都不可以)
str.isidentifier()#判斷給定的字符串是否符合命名規則(只能是字母或下划線開頭 不能包含除數字 字母和下划線以外的任意字符
str.startswitch(str)#字符以str開頭 返回True False
str.endswitch(str)#字符以str結尾 返回True False 可用於判斷擴展名
str.count(str,start,end)#計數str在字符串中出現的次數
l,c,r=str.partition(str)#由字符串中str位置切分成三個字符串
str=str.join(iter)
list=str.split(split_str)#返回分割后的列表
str=str.strip(default_str=' ')#刪除字符串頭尾指定的所有str 不能去除所有
str=str.replace(old,new,times)#去除所有
str.encode(encoding)#編碼
str.decode(encoding)#解碼
#encoding
encoding='UTF-8'#一個漢字占3個字節
encoding=ASCII#一個字符占1個字節
encoding=ANSI
encoding=GBK#一個漢字占2個字節
encoding=GB2312
encoding=GB18030
encoding=UNICODE
'\n'#換行
'\t'#tab
'\r'#回車 將光標移動到本行開頭
#enter=\r\n
#* 和 ** 有四類用法
* #代表乘法
** #代表乘方
*args **kwargs #主要用於函數定義 都是 python 中的可變參數
def func(arg,arg=default,*args, **kwargs):
#如果同時使用 *args 和 **kwargs 時 必須 *args 參數列要在 **kwargs 之前
*args #表示任何多個無名參數 它本質是一個 tuple
def func(name, *args):
print('你好:', name)
for i in args:
print("你的寵物有:", i)
>>> func("Geek", "dog", "cat")
你好: Geek
你的寵物有: dog
你的寵物有: cat
**kwargs #表示關鍵字參數 它本質上是一個 dict
def func(**kwargs):
for key, value in kwargs.items():
print("{0} 喜歡 {1}".format(key, value))
>>> func(Geek="cat", cat="box")
Geek 喜歡 cat
cat 喜歡 box
#用 *args 和 **kwargs 調用函數 類似對元組和字典進行解引用
def func(data1, data2, data3):
print(data1, data2, data3)
args=("one", 2, 3)
kwargs={"data3": "one", "data2": 2, "data1": 3}
func(*args) >>> one 2 3
func(**kwargs) >>> one 2 3
*#序列解包 **不能
a, *b,c= 0, 1, 2, 3,4
>>>a=0
>>> b=[1,2, 3]
>>> c=4
a,*b=1
>>>a=1,b=[]
s='ABCDEFGH'
while s:
x, *s=s
print(x, s)
>>>
A ['B', 'C', 'D', 'E', 'F', 'G', 'H']
B ['C', 'D', 'E', 'F', 'G', 'H']
C ['D', 'E', 'F', 'G', 'H']
D ['E', 'F', 'G', 'H']
E ['F', 'G', 'H']
F ['G', 'H']
G ['H']
H []
#隨機
import random
random.seed(num)# 初始化給定的隨機數種子 默認為當前系統時間 隨機出一個數字 且保證以后的隨機數都是這個數字
random.random()#生成一個[0.0,1.0)之間的隨機小數
random.randint(a,b)#int [a,b]
random.randrange(a,b,k)#int [a,b) step k
random.getrandibits(k)#int 生成一個k比特長的隨機整數
random.uniform(a,b)#float [a,b]
random.choice(iter)#choice one from iter
random.shuffle(iter)#打亂iter
#排列組合
import itertools
#repeat 表示組合位數
i_list=itertools.product(iter, digit)#笛卡爾積
i_list=itertools.permutations(iter, digit)#排列 digit是排列組合的位數 若不填 默認返回全部排列組合情況
i_list=itertools.combinations(iter, digit)#組合
i_list=itertools.combinations_with_replacement(iter, digit)#組合 含自身重復
#連接詞
and #有一個False 輸出就為False
or #有一個True 輸出就為True
if (var1 in sth) or (var2 in sth):#判斷兩個變量和另一個變量之間的關系
不要使用這種語句 判斷會出錯#if (var or var) in sth:
#列表全為False
any(iter)#iter中至少一個值為True 就返回True
#列表全為True
all(iter)#iter中每個值為True 才返回True
#程序中斷
break #for or while 跳出並結束一層循環
continue #for or while 跳回到該層循環開頭
sys.exit() #結束程序 import sys
return #def 返回值並跳出函數
yield #def 返回值並跳出函數 下次直接從yield后的一條語句開始運行函數
pass #* 跳過該處代碼
#運算符
** #^
% #取余數
// #取整數商數
** % // / *-+#數學運算符優先級
+= -= *= /= %=#符號運算簡寫
== = #比較值
is #比較內存地址
#運算函數
complex(real,imagnum)#創建復數(real + imagnumj)
complex('realnum+imagnumj')#將字符轉為復數
quot,rem=divmod(7,2) #返回商和余數
r=round(float,digit)#返回digit位小數的float 四舍六入五成雙
from decimal import Decimal, ROUND_HALF_UP#實現精確的四舍五入
answer_num = Decimal('11.245').quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
>>>11.25
answer_num = Decimal(str(float)).quantize(Decimal('0.digit'), rounding=ROUND_HALF_UP)
r=format(float,'.0%')#返回0位小數的百分數
abs_value=abs(num)#返回絕對值
r=pow(x,y,z=None)#返回x的y次方 如果z存在 返回pow(x,y)%z
r=sum(iter,value=0)#返回iter相加后再和value相加的結果
cmp(x,y)#如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1
binary=bin(int)#返回int二進制
hash(obj)#返回哈希值
hex()#十進制轉為十六進制 字符串形式表示
oct()#十進制轉為八進制 字符串形式表示
id(obj)#返回對象內存地址
dir(obj)#返回對象屬性 函數列表
#運算模塊
import math#數學函數
import cmath#復數函數
#迭代器 列表 字符串等有順序的都是迭代器
iter(iter)#生成迭代器
next(iter,default)#返回迭代器的下一個項目 next() 函數要和生成迭代器的 iter() 函數一起使用
s=slice(start,stop,step)#切片
iter[s]#截取片段
content_iter=(line for line in open(file))#返回迭代器 而不是file的內容 只能用()
print(next(content_iter))#每次返回下一行line
print(next(content_iter))
#布爾值
bool(var)#返回布爾值
0 0.0 None [] () {} '' "" return None#布爾值為 False
assert True_code,False_code#斷言 程序正常運行調用True_code,程序出錯調用False_code
#等效
var='str'
if var == '':
if not var != '':
if var == False:
if not var:
if False:
#等效
var=1
while var != 0:
while var != False:
while var == True:
while var:
while True:
#范圍
range(0,3) # 0 1 2 不含3
range(3,0,-1) # 3 2 1
#全局變量
global#全局作用域不能使用局部作用域變量
#local #局部作用域能使用全局作用域變量
def func():
global var#聲明全局變量
var #在函數內部創建全局變量
locals()#以字典類型返回當前位置全部局部變量
globals()#函數會以字典類型返回當前位置的全部全局變量
def func():
def inner():
nonlocal var#聲明非局部變量
var
#異常處理
try: #可能異常的代碼
except ERROR as e: #處理異常 捕捉異常
else:#沒有發生異常時的代碼
finally:#是否發生異常都執行的代碼
#寫代碼時要主動考慮使用程序時會產生的異常情況
raise Exception()#引起異常
raise ValueError(str)#通用自定義異常提示
class Cust_Exc(Exception):#自定義異常
"""docstring for Cust_Exc"""
def __init__(self, msg):
self.msg=str
def __str__(self):
return self.msg
raise Cust_Exc(str)
#比較大小
max(iter)
min(iter)
#列表
for index,element in enumerate(list,num):#索引和元素 num可以不寫 num表示index的初始值 默認index=num=0 用enumerate代替range
list[index]=new_element#修改元素的方法一 不能用for循環直接更改
for index in range(len(list)):#修改元素的方法二 不能用for循環直接更改 不建議用這種
list[index]=new_element
l=list()
list1_2=list1+list2
list1_2=list(set(list1)-set(list2))#list相減
a=[1,2,3,4] a[0:-1]=[1,2,3] a[1:4]=[2,3,4] a[:2]=[1,2]
list[*start:end:step,]#切片含頭不含尾 多層之間用,分隔
list=[[*ele],[*ele],[*ele],[*ele],[*ele],[*ele]]
list[1:3,:3]#二維列表 list中索引為1-2的元素中 索引為0-2的元素
list[::-1]#反轉字符串
del list[index]
list.index(value) #返回value第一次出現的索引
list.append(value) #value will be the last in the list
list.extend(iter) #iter will be the last in the list
list.insert(index,value) #將指定對象插入列表的指定位置
list.remove(value) #value firstly appearing will be removed from the list
poped=list.pop(index)
poped=list.pop()#default index -1
list.sort()#the values of list will be arranged in order (must be the same type)
list.sort(reverse=True) #the values of list will be arranged in order in reverse
list.sort(key=func)#func need to definite
list.sort(key=str.lower) #the values of list will be arranged in order (ignore a or A type)95
def take_sec(itr):
return itr[1]
[(2, 2), (3, 4), (4, 1), (1, 3)].sort(key=take_sec)#指定第二個元素排序
#列表中的值可改 元組和字符不可
#不可變的值(字符元組整型etc) python變量保存本身 可變的值(列表字典) 引用本身
list=[x func_condition]#列表條件 處理元素
list=[x**x for x in range(n)]
matrix=[[1,2,3],[4,5,6]]
flat=[x for row in matrix for x in row]#二維轉一維
squared=[[x**2 for x in row]for row in matrix]#對每個元素平方
#排序
new=sorted(iter,key=key_func)
new=reversed(iter)
class Student:
def __init__(self, name, grade, age):
self.name=name
self.grade=grade
self.age=age
def __repr__(self):
return repr((self.name, self.grade, self.age))
students_list=[Student('john', 'A', 15),
Student('jane', 'B', 12),Student('dave', 'B', 10),]
s=sorted(students_list, key=lambda student: student.age) # sort by age
>>>[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
from operator import attrgetter
s=sorted(students_list, key=attrgetter('grade', 'age'))#先以grade再以age來排序
>>>[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
#字典
a=dict()
dict[key]=value
reversed_dict={value:key for key,value in dict.items()}#反轉字典
key in dict #CANNOT use value in dict
value in dict.values()
key in dict.keys()
key-value in dict.items()
value=dict.get(key,defaultvalue=None) #如果鍵不存在於字典中 將會返回默認值
del dict[key]
dict.clear()
dict.update(dict2)
poped=pop(key)
poped=popitem()#return and del the last item
d=dict(zip(iter1,iter2))
dict.setdefault(key,defaultvalue)#如果鍵不存在於字典中 將會添加鍵並將值設為默認值
for key,value in [(key,value),]:#元組列表轉字典形式
dict[key]=value
#元組 unmodifiable
t=tuple()
(0,1,200000)<(0,3,4) #return True 有一個不同且能比較 比較后返回結果 不再繼續比較后續元素
func(*tuple) #拆分元組
#集合 可用於去重復元素 但會打亂順序
{}=set()
list1_2=list(set(list1)-set(list2))#list相減
a=frozenset(iter)#返回一個不可變的集合
#函數
def func(*args):#任意多個參數
def func(a,ar,arg=default):#defaultvalue
def func(arg,arg=default,*args, ):#參數 參數默認值 可變參數(元組列表類型)
def func(**kwargs):#可變參數(字典類型)
print(a,b,c)#輸出字典值1 2 3
func(**{'a': 1, 'b': 2, 'c': 3})#使用**時 字典鍵必須和函數參數名字一致 否則出錯
map(func,iterable)#函數映射到迭代器
list=filter(func,iter)#過濾出符合func的元素
#壓縮迭代器 一一對應 取最短的iter
z=zip(*iter)#z=(val1_1,val2_1)(val1_2,val2_2)(val1_3,val2_3)
z=list(zip(iter1),iter2)#[(1,1),(2,2)]
z=itertools.zip_longest(*iter)#取最長的iter
#時間
unix時間戳 從1970.01.01 0:0:0 開始到現在一共的秒數 只能表示1970-2038的時間
1 分鍾 60
1 小時 3600
1 天 86400
1 周 604800
1 月 (30.44 天) 2629743
1 年 (365.24 天) 31556736
import time
time.time() #返回當前unix時間戳(float) time模塊中的函數默認值都為time.time()
time.sleep(sec)#程序推遲執行的秒數
struct_time_tuple=time.gmtime(unix_time_stamp)#unix時間戳轉0時區struct_time類
時間戳(float)轉字符串(str) 轉出來的時間是UTC時區(0時區)的struct_time 但是我們計算機顯示的是東八區時間(+8) 所以的得到的struct_time+8即為現在計算機顯示的時間
時間轉換與所在時區有關
print(struct_time_tuple)
>>>time.struct_time(tm_year=2016, tm_mon=4, tm_mday=7, tm_hour=2, tm_min=55, tm_sec=45, tm_wday=3, tm_yday=98, tm_isdst=0)
0 tm_year #年份 其值等於實際年份減去1900
1 tm_mon #月份(從一月開始 0代表一月)-取值區間為[0,11]
2 tm_mday #一個月中的日期-取值區間為[1,31]
3 tm_hour #時-取值區間為[0,23]
4 tm_min #分-取值區間為[0,59]
5 tm_sec #秒 – 取值區間為[0,59]
6 tm_wday #星期 – 取值區間為[0,6] 其中0代表星期一 1代表星期二 以此類推
7 tm_yday #從每年的1月1日開始的天數 – 取值區間為[0,365] 其中0代表1月1日 1代表1月2日 以此類推
8 tm_isdst #夏令時標識符 實行夏令時的時候 tm_isdst為1 不實行夏令時的時候 tm_isdst為0 不了解情況時 tm_isdst()為-1
local_struct_time_tuple=time.localtime(unix_time_stamp)#unix時間戳轉本地struct_time類
secs=time.mktime(local_struct_time_tuple)#本地struct_time類轉unix時間戳 mktime 輸入的日期是帶時區的 返回的值才是不帶時區的 直接用 gmtime(0) 生成的 date 組裝成數組輸入 mktime 則會報超出范圍的錯誤
str_time=time.strftime(str_format,struct_time_tuple)#struct_time轉字符串時間格式
struct_time_tuple=time.strptime(str_time,str_format)#字符串時間格式轉struct_time
'Tue Feb 17 09:42:58 2009'=time.asctime(time.gmtime() or time.localtime())#接受時間元組並返回一個可讀的形式
'Tue Feb 17 10:00:18 2013'=time.ctime(sec)#相當於time.asctime(localtime(secs))
1530000078.0=time.mktime(time.strptime('2018-06-26 16:01:18', '%Y-%m-%d %H:%M:%S'))#字符串時間格式轉為unix時間戳
datetime_class=datetime.strptime('2018-06-26 16:01:18', '%Y-%m-%d %H:%M:%S')#字符串轉為datetime類(datetime.datetime)
'Sat Mar 28 22:24:24 2016'=time.strftime('%a %b %d %H:%M:%S %Y', time.gmtime(1530000078.0))#unix時間戳轉為字符串時間格式
datetime_class=datetime.strptime(time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(1530000078.0)), '%Y-%m-%d %H:%M:%S')#unix時間戳轉datetime類
'2018-06-26 16:01:18'=time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime(1530000078.0))#datetime類轉為字符串時間格式
time_stamp=float(time.mktime(time.strptime(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime(1530000078.0)), '%Y-%m-%d %H:%M:%S')))#datetime類轉為unix時間戳
str_time=time.strftime("%Y-%m-%d %H:%M:%S",datetime(year=1900, month=1, day=1)+datetime.timedelta(days=excel_datetime)) #datetime類轉為字符串時間格式 excel_datetime 從excel讀出的float日期 eg 44152.0146412037
#常用時間處理
today=datetime.date.today()#今天
yesterday=today-datetime.timedelta(days=1)#昨天
last_month=today.month-1 if today.month-1 else 12#上個月
time_stamp=time.time()#當前時間戳
datetime.datetime.fromtimestamp(time_stamp)#時間戳轉datetime
int(time.mktime(today.timetuple()))#datetime轉時間戳
today_str=today.strftime("%Y-%m-%d")#datetime轉字符串
today=datetime.datetime.strptime(today_str, "%Y-%m-%d")#字符串轉datetime
today + datetime.timedelta(hours=8)#補時差
#datetime
import datetime
datetime.date.today()#返回當前字符串日期
datetime.date.fromtimestamp(time_stamp)#時間戳轉字符串日期
d=datetime.date(year,month,day)
d.year
d.month
d.day
d.replace(newyear,newmonth,newday)
d.timetuple()#返回struct_time
d.isocalendar()#返回格式如(year month day)的元組
d.isoformat()#返回格式如'YYYY-MM-DD’的字符串
t=datetime.time(hour,minute,second)
t.hour
t.minute
t.second
t.replace(newhour,newminute,newsecond)
t.isoformat()#返回格式如'HH:MM:SS’的字符串
datetime.datetime.today()#返回一個表示當前本地時間的datetime對象
datetime.datetime.now(time_zone)#返回一個表示當前本地時間的datetime對象 如果提供了參數time_zone 則獲取tz參數所指時區的本地時間
datetime.datetime.utcnow()#返回一個當前utc時間的datetime對象#格林威治時間
datetime.datetime.fromtimestamp(time_stamp,time_zone)#根據時間戳創建一個datetime對象 參數tz指定時區信息
datetime.datetime.utcfromtimestamp(time_stamp)#根據時間戳創建一個datetime對象
datetime.datetime.combine(date,time)#根據date和time 創建一個datetime對象
datetime.datetime.strptime(date_string,format)#將格式字符串轉換為datetime對象
dt=datetime.datetime(year,month,day,hour,minute,second)
dt.year month day hour minute second microsecond timezone
dt.date()#獲取date對象
dt.time()#獲取time對象
dt.replace(year, month, day, hour, minute, second, microsecond, timezone)
dt.timetuple()
dt.utctimetuple()
dt.isocalendar()
dt.isoformat(sep)
dt.ctime()#返回一個日期時間的C格式字符串 等效於time.ctime(time.mktime(dt.timetuple()))
dt.strftime(format)
dt.number_format#'yyyy-mm-dd h:mm:ss'
datetime.timedelta(days=v,seconds=v,weeks=v,minutes=v,hours=v,microseconds=v)#時間計算 不能計算年月 只能和datetime類計算
#dateutil 用於datetime時間處理
from dateutil.parser import parse
parse('date_string')#任意正常日期格式轉為datetime.datetime(year,month,day,hour,minute,sec)
#年份放在前面時 只能按年-月-日的順序
#分隔符為逗號時 只有月-日時 要把月放在前面 有年份時 年份要放在后面
parse("2018/10/21")
>>> datetime.datetime(2018, 10, 21, 0, 0)
from dateutil.rrule import rrule
rrule(freq, dtstart=None, interval=1, wkst=None,count=None, until=None, bysetpos=None,bymonth=None, bymonthday=None, byyearday=None, byeaster=None,byweekno=None, byweekday=None, byhour=None, byminute=None, bysecond=None)
freq#單位 可以是 YEARLY, MONTHLY, WEEKLY,DAILY, HOURLY, MINUTELY, SECONDLY 即年月日周時分秒
dtstart,until#是開始和結束時間
wkst#周開始時間
interval#間隔
count#只保留幾個
byxxx#指定匹配的周期 比如byweekday=(MO,TU)則只有周一周二的匹配 byweekday可以指定MO,TU,WE,TH,FR,SA,SU 即周一到周日
list(rrule(DAILY,byweekday=(SA,SU),dtstart=parse('2018-11-1'),until=parse('2018-11-5')))#只要周六和周日的
>>>[datetime.datetime(2018, 11, 3, 0, 0),
datetime.datetime(2018, 11, 4, 0, 0)]
rrule(freq,dtstart=parse('date'),until=datetime.date.today()).count()#計算某個日期到今天相差freq數
#calendar 日歷
import calendar
calendar.calendar(year,w=2,l=1,c=6)#返回一個年歷 3個月一行 間隔距離為c 每日寬度間隔為w字符 l是每星期行數 不填會設置為默認間距
calendar.isleap(year)#是閏年返回 True 否則為 False
calendar.leapdays(y1,y2)#返回在Y1 Y2兩年之間的閏年總數
calendar.month(year,month,w=2,l=1)#返回一個多行字符串格式的year年month月日歷 兩行標題 一周一行 每日寬度間隔為w字符 l是每星期的行數 不填會設置為默認間距
calendar.timegm(tupletime)
#和time.gmtime相反接受一個時間元組形式 返回該時刻的時間戳(1970紀元后經過的浮點秒數)類似time.mktime()
calendar.monthrange(year,month)#返回(星期幾,這月有幾天)
days_list=calendar.mdays#當年每個月的天數組成的列表
#判斷類型
type(obj)#return type
isinstance(n,type)#return True or False
#復制 拷貝
import copy
copy.copy()#賦值 拷貝
copy.deepcopy()#深拷貝
origin=[1, 2, 3, 4, ['a', 'b']] #原始對象
assigned=origin#賦值 傳對象的引用 兩者的子對象(列表里的每個元素)父對象(列表本身)是同一個 讓兩個變量的數據相同 且是同一個變量
copied=copy.copy(origin)#對象拷貝 淺拷貝 兩者的子對象是同一個 父對象是獨立的兩個 讓兩個變量的數據相同 是同一個數據 但不是同一個變量
deepcopied=copy.deepcopy(origin)#對象拷貝 深拷貝 兩者的子對象父對象分別是值相同的獨立兩個 讓兩個變量的數據在最初相同 但不是同一個數據 也不是同一個變量
origin.append(5)#修改對象origin
origin[4].append('c') #修改對象origin中的['a', 'b']數組對象
>>>origin=[1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>>assigned=[1, 2, 3, 4, ['a', 'b', 'c'], 5]
>>>copied=[1, 2, 3, 4, ['a', 'b', 'c']]
>>>deepcopied=[1, 2, 3, 4, ['a', 'b']]
#代碼優化 略
import profile
from logging import basicConfig,DEBUG,debug,CRITICAL,disable#日志模塊 記錄調試信息 可以直接寫在文件頭
#disable(CRITICAL)#禁用日志 在程序完成之后 將最前面的#取消
basicConfig(level=DEBUG, format='%(levelname)s: %(message)s. [%(lineno)d]%(filename)s <%(asctime)s>',filename='debug.log',filemode='w')#配置日志輸出格式 以'w'模式寫入debug.log儲存在程序同級目錄
debug(str)#用來記錄調試信息 str將表示在%(message)s中
#format
%(levelno)s#打印日志級別的數值
%(levelname)s#打印日志級別名稱
%(pathname)s#打印當前執行程序的路徑 等於sys.argv[0]
%(filename)s#打印當前執行程序名
%(funcName)s#打印日志的當前函數
%(lineno)d#打印日志的當前行號
%(asctime)s#打印日志的時間
%(thread)d#打印線程ID
%(threadName)s#打印線程名稱
%(process)d#打印進程ID
%(message)s#打印日志信息
#日志級別 日志函數
logging.DEBUG logging.debug()#小細節
logging.INFO logging.info()#一般信息
logging.WARNING logging.warning()#警告
logging.ERROR logging.error()#錯誤
logging.CRITICAL logging.critical()#致命錯誤
#另一種Bug處理方式 idle調試器debugger 略
#讀寫文件
f=open(filename,mode,encoding='UTF-8')#以mode模式 以UTF-8編碼 打開或創建filename 不用utf-8可能引起異常
#encoding參數 Window上默認字符編碼為GBK Linux上默認字符編碼為UTF-8
encoding='UTF-8'#一個漢字占3個字節
encoding=ASCII#一個字符占1個字節
encoding=ANSI
encoding=GBK#一個漢字占2個字節
encoding=GB2312
encoding=GB18030
encoding=UNICODE
str.decode(encoding)#若字符亂碼 修改解碼方式
#mode
'r'#以 只讀模式 打開文件 並將文件指針指向文件頭 如果文件不存在會報錯
'w'#以 只寫模式 打開文件 並將文件指針指向文件頭 如果文件存在則將其內容清空 如果文件不存在則創建
'a'#以 只追加可寫模式 打開文件 並將文件指針指向文件尾部 如果文件不存在則創建
'r+'#在r的基礎上增加了可寫功能,會覆蓋當前文件指針所在位置的字符 如原來文件內容是"Hello World" 打開文件后寫入"hi"則文件內容會變成"hillo, World"
'w+'#在w的基礎上增加了可讀功能,在打開文件時就會先將文件內容清空
'a+'#在a的基礎上增加了可讀功能, 並將文件指針指向文件尾 只能寫到文件末尾(無論當前文件指針在哪里)
如果以此種方式打開直接讀取文檔 會返回空值 使用f.seek(0, 0) 使文件指針指向文檔開頭
'b'#讀寫二進制文件(默認是t 表示文本) 需要與上面幾種模式搭配使用 如ab wb, ab, ab+(POSIX系統 包括Linux都會忽略該字符)
str_read=f.read()#讀取內容
f.close()#關閉文件
with open(filename,mode,encoding) as f:#f.open()和f.close()的簡化
for line in f:#推薦這種方式 內存消耗小
print(line,end='')#避免print方法造成的換行
content=f.read()#一次讀取文件所有內容 返回一個str
content=f.read(int_size)#每次最多讀取指定長度的內容 返回一個str 在Python2中size指定的是字節長度 在Python3中size指定的是字符長度
content_list=f.readlines()#一次讀取文件所有內容 按行返回一個list
line_string=f.readline()#每次只讀取一行內容
f.seek(n)#將文件指針移動到指定字節的位置
f.seek(0, 0)#將文件指針移動到文檔開頭位置
f.tell() #獲取當前文件指針所在字節位置
str_amount=f.write(str)#返回寫入字符的數量並寫入字符
next_line=f.next()#返回文件下一行 這個方法也是file對象實例可以被當做迭代器使用的原因
f.writelines(iter)#向文件寫入一個字符串列表 字符串需要自己添加換行符
#shelve 二進制儲存數據
import shelve
shelf_file = shelve.open('shelf_name')#打開或創建shelf_name
shelf_file['data_name'] = data#shelf_file可以看作一個字典
shelf_file.close()#會在程序同居目錄生成.bak .dat .dir三個文件進行二進制儲存數據
#操作系統
#os operating system
import os
.#當前工作目錄簡寫 .\
..#當前工作目錄的上一級目錄簡寫 ..\
os.system(r'str')#在cmd運行str語句
str=os.popen(r'str')#在cmd運行str語句 且返回str
cwd=os.getcwd()#返回當前工作目錄
cwd=os.chdir(path)#改變當前工作目錄
fullpath=os.path.abspath(path)#返回目錄絕對路徑
print(os.path.exists(path))#返回目錄存在布爾值
print(os.path.isabs(path))#返回目錄存在布爾值
if os.path.exists(out_dir)==False: os.mkdir(out_dir)#如果輸出文件夾不存在 創建out_dir文件夾
os.mkdir(dirname)#創建一層文件夾
os.makedirs('D:\\folder1\\folder2\\folder3\\...')#創建多層文件夾
os.remove(fullpath)#只用於移除文件和文件夾
os.rename(old_file_path, new_file_path)#只能對相應的文件進行重命名, 不能重命名文件的上級目錄名
os.renames(old_file_path, new_file_path)#是os.rename的升級版, 既可以重命名文件, 也可以重命名文件的上級目錄名 不是新建目錄
os.unlink(fullpath)#永久刪除 path 處的文件
os.rmdir(fullpath)#永久刪除 path 處的文件 只能刪除空文件夾
os.removdirs(fullpath)#只能永久刪除空文件夾 目錄 將整個目錄刪除
os.utime(fullpath, (accessed_time_stamp,modified_time_stamp))#修改文件的訪問時間 改動時間 時間格式為unix時間戳
print(os.path.isdir(fullpath))#返回是否目錄或文件夾布爾值
print(os.path.isfile(fullpath))#返回是否文件布爾值
files_list=os.listdir(dirname)#返回該目錄內的第一層文件夾和文件列表
import fnmatch
for filename in os.listdir(dirname):
if fnmatch.fnmatch(filename,'*.txt'):pass#匹配目錄中所有.txt文件
(root,dirs_list,files_list)=os.walk(root,topdown=True)#返回該目錄內的所有文件名列表 包含所有級目錄的元組
#topdown 默認為True 會優先遍歷root目錄 False 優先遍歷root子目錄
#root是文件本身目錄 相當於dirname
#dirs_list是該文件夾所有目錄名字的列表(不含子目錄)
#files_list是該文件夾所有文件名字的列表(不含子目錄)
for root, dirs, files in os.walk(root):
for name in files:#拼接文件名
print(os.path.join(root, name))
for name in dirs:#拼接目錄名
print(os.path.join(root, name))
fullpath=os.path.join(dirname,filename)#拼接目錄和文件名 返回絕對路徑
(dirname,filename)=os.path.split(fullpath)#返回路徑與文件名組成的元組 不含/
(file_name,extension)=os.path.splitext(filename)#返回文件名字和后綴(擴展名 含.)組成的元組
['C:', 'Windows', 'System32', 'calc.exe']='C:\\Windows\\System32\\calc.exe'.split(os.path.sep)#根據使用的系統判斷使用\還是/分割
dirname=os.path.dirname(fullpath)#返回目錄路徑 D:\folder1\folder2
filename=os.path.basename(fullpath)#返回文件名 *.*
accessed_time=os.path.getatime(filename)#輸出最近訪問時間 累計秒格式
created_time=os.path.getctime(filename)#輸出文件創建時間 累計秒格式
modified_time=os.path.getmtime(filename)#輸出最近修改時間 累計秒格式
clear_time=time.gmtime(os.path.getmtime(filename))# 以struct_time形式輸出最近修改時間
>>>clear_time=time.struct_time(tm_year=2016, tm_mon=4, tm_mday=7, tm_hour=2, tm_min=55, tm_sec=45, tm_wday=3, tm_yday=98, tm_isdst=0)
file_size=os.path.getsize(filename)#輸出文件大小 以字節為單位
from pyperclip import copy,paste#訪問剪貼板
copy(str)#復制到剪切板 只支持文本內容
str=paste()#粘貼文本
import sys
script_name=sys.argv[0]#0代表程序本身完整目錄 1: 代表從cmd接受的每個參數 以空格分割
user_argv=sys.argv[1]
user_argv_list=sys.argv[1:]
cmd輸入 script.py -argv1 a2 d
>>>argv_list=['script.py','-argv1','a2','d']
import shutil#復制 移動 改名 刪除文件
destination_file_path=shutil.copy(source_file_path,destination_file_path)#將 source_file_path 復制到 destination_file_path 返回 destination_file_path 只能復制文件
destination_path=shutil.copytree(source_path,destination_path)#將 source_path 復制到 destination_path 返回 destination_path 用於復制文件夾 包括文件夾內的所有文件和文件夾
destination_path=shutil.move(source_path,destination_path)#將 source_path 移動到 destination_path 返回 destination_path 會覆蓋和 destination_path 同名的文件 destination_path 中的文件夾目錄必須存在 否則會異常 如果文件名不存在 會創建
shutil.rmtree(path)#永久刪除path文件夾 包含所有子文件和文件夾
import send2trash#需要安裝模塊
send2trash.send2trash(filename)#移動到回收站
#fnmatch 主要用於文件匹配 目錄匹配 正則表達的簡化模塊
import fnmatch,os
* #匹配任意字符
? #匹配單個字符
[seq] #匹配指定范圍內字符
[!seq] #匹配不在指定范圍內字符
fnmatch.fnmatch(filename, 'pattern')#匹配符合pattern的filename
fnmatch.fnmatchcase(filename, 'pattern')#強制區分大小寫進行匹配 和fnmatch一樣
fnmatch.filter(list, 'pattern')#在list中匹配符合pattern模式的元素
regex=fnmatch.translate('pattern')#將'pattern'轉為正則表達式進行匹配
for filename in os.listdir(dirname):
if fnmatch.fnmatch(filename,'*.txt'):pass#匹配目錄中所有.txt文件
#glob 主要用於文件匹配
import glob
*#匹配0個或多個字符
?#匹配單個字符
[]#匹配指定范圍內的字符 如 [0-9]匹配數字
for n in glob.glob('pattern'):#同時獲取所有的匹配路徑
for n in glob.iglob('pattern'):#一次只獲取一個匹配路徑
import zipfile#壓縮模塊
zip_file=zipfile.ZipFile('zip_file.zip')#創建 ZipFile 對象
zip_dir_list=zip_file.namelist()#返回zip文件里的所有文件目錄組成的列表 如
zip_file.zip
cats_folder
catnames.txt
zophie.jpg
spam.txt
>>>zip_dir_list=['spam.txt', 'cats_folder/', 'cats_folder/catnames.txt', 'cats_folder/zophie.jpg']
spam_info=zip_file.getinfo('spam.txt')#返回spam.txt的信息對象
spam_info.file_size#原文件大小 字節單位
spam_info.compress_size#壓縮后文件大小 字節單位
zip_file.extractall('path')#解壓到path目錄 不存在會被創建 默認為程序同級目錄
outpath=zip_file.extract('filename','path')#解壓單個filename到path目錄 不存在會被創建 默認為程序同級目錄 返回path目錄
zip_file.write('add_filename',compress_type=zipfile.ZIP_DEFLATED)#用deflate算法將add_filename壓縮進zip_file
zip_file.close()#壓縮包不使用一定要關閉
#類 任何對象都可以定義類 例如 學校-年級-班級-學生-成績 每一層都是一個類 數據層次太多必須用類 否則數據難以處理
class ClassName(object):
"""docstring for ClassName"""
def __init__(self, arg=defaultvalue):
super(ClassName, self).__init__()
self.arg=arg
self.__private_arg=0 #私有變量 不能在類的外部調用 只能在類本身調用 用__在變量開頭聲明
self._protected_arg=0 #保護變量 只能本身和子類使用 不能作為模塊引入 不能使用import訪問 在變量開頭聲明
self.public_arg=0# 公開變量
def __special_func__(self):#特殊方法 系統定義 用__在函數開頭結尾聲明
def count(self):
self.__private_arg += 1# 私有變量
def __str__(self):#當使用print(ClassName)時將調用該方法
return '{}'.format(self.arg)
def __del__(self):#銷毀對象
class_name=self.__class__.__name__
print('has been deled')
def __customize_func__(self.arg):pass#自定義方法 可以讓類與類之間進行運算 對於每一種運算符 都有一種對應方法 稱為運算符重載
def function(self):pass
del instance>>>'has been deled'
instance=ClassName(arg)#類的實例化
instance.arg=value
instance.arg=ClassName2(arg)
print(ClassName.__doc__)#返回類注釋
print(instance)#調用__str__()
hasattr(obj,attr)#返回對象屬性存在布爾值
getattr(obj,attr,default)#返回對象屬性值 如果沒有屬性值又沒有設置默認值 會異常
setattr(obj,attr,value)#設置屬性值 屬性不一定要存在
delattr(obj,attr)#屬性必須存在
issubclass(subclass,supclass)#如果subclass是supclass子類返回True
help(obj)#返回對象幫助信息
#collections 工具集合
import collections
#Counter 計數器
count_dict=collections.Counter(iter)#計數字典
most_list=count_dict.most_common(int)#按鍵出現次數從高到低排序 返回前int個鍵值對分別組成的元組 所構成的列表
count_list=count_dict.elements()#返回計數字典的所有鍵組成的列表 包含每一次
count_dict.update(dict2)#並集
count_dict.substract(dict2)#交集
count_dict.iteritems()#返回所有item
count_dict.iterkeys()#返回所有key
count_dict.itervalues()#返回所有value
for val,freq in count_dict:pass
#deque 雙向隊列
deque_seq=collections.deque(iter)
deque_seq.append()#隊列右邊添加元素
deque_seq.appendleft()#隊列左邊添加元素
deque_seq.clear()#清空隊列中的所有元素
deque_seq.count()#返回隊列中元素的個數
deque_seq.extend()#隊列右邊擴展 可以是列表 元組或字典 如果是字典則將字典的key加入到deque
deque_seq.extendleft()#同extend 在左邊擴展
deque_seq.pop()#移除並返回隊列右邊的元素
deque_seq.popleft()#移除並返回隊列左邊的元素
deque_seq.remove(value)#移除隊列第一個出現的元素
deque_seq.reverse()#隊列的所有元素進行反轉
deque_seq.rotate(index)#以index為中心 把所有元素索引進行旋轉
#defaultdict 默認字典
default_dict=collections.defaultdict(dict)#繼承普通字典 同時鍵值對有默認值 即使鍵還不存在
#OrderedDict 有序字典 繼承普通字典 同時鍵值對有順序
#namedtuple 可命名元組
named_tuple=collections.namedtuple(*attr)
tuple_name=named_tuple(*attr_value)#對元組命名
#openpyxl excel表格處理
import openpyxl#需要安裝 pip install openpyxl
from openpyxl import Workbook
xlsx=Workbook()#創建xlsx
xlsx=openpyxl.load_workbook(filename,data_only=False)#打開xlsx文件 類的實例化 data_only=True返回單元格的計算后的值 False將返回單元格的原字符串
xlsx.sheetnames#xlsx文件所有sheet名字組成的列表 只能引用 不能命名
xlsx.save(filename.xlsx)#程序結束時使用 只支持xlsx格式
xlsx.remove(sheet_name)#刪除sheet
del xlsx['sheet_name']#刪除sheet
copy_sheet=xlsx.copy_worksheet(source_xlsx)#sheet副本
sheet=xlsx.create_sheet('sheet_name',index)#新建sheet 插到索引位 索引值從0開始 不填默認插到最后
sheet=xlsx.active#激活的sheet 相當於xlsx打開后默認顯示的sheet
sheet=xlsx['sheet_name']#打開xlsx中對應名字的sheet
sheet.title#表格名字 只能引用 和更改 不能命名
sheet.append(list)#寫入行 從左下角第一個空單元格開始向右填充值 最多嵌套兩層列表 列表中的列表表示行 列表的元素表示單元格值
for row in sheet.values:#sheet所有值數據 不包含值格式
for value in row:pass
sheet.sheet_properties.tabColor='1072BA'#改變sheet標簽顏色
sheet.max_row#最大行 只能引用 不能命名
sheet.max_column#最大列 只能引用 不能命名
sheet.row_dimensions[num_index].height = 40#行高 類似列表切片 默認12.75
sheet.column_dimensions['letter_index'].width = 30#列寬 類似列表切片 默認8.43
sheet.merge_cells('A1:C3')#合並一個矩形區域中的單元格
sheet.unmerge_cells('A1:C3')#拆分一個矩形區域中的單元格 只會保留左上角值在左上角單元格
sheet.freeze_panes='coordinate'#凍結行 列 滾動sheet時 凍結的行列不會被滾動
list(sheet.rows)#所有行 每行單元格共組成一個元組 所有元組組成一個生成器
list(sheet.columns)#所有列 每列單元格共組成一個元組 所有元組組成一個生成器
a1=sheet['A1']#單元格 'ColumnRow'
a1.value#單元格值 只能引用 不能命名 如果是日期格式 會自動轉為datetime.datetime()類
a1.row#單元格行值 只能引用 不能命名
a1.column#單元格列值 只能引用 不能命名
a1.coordinate#單元格坐標 只能引用 不能命名
a1=sheet.cell(row=row_num,column=col_num,value=None)#把value寫入excel 用數字來代替字母形式 數字從1開始 而不是0 value填充會覆蓋單元格值 不寫將返回單元格原有的值
from openpyxl.utils import get_column_letter, column_index_from_string
get_column_letter(int)#返回數字對應的列的字母
column_index_from_string('letter')#返回字母對應的列的數字
a1=value#填充值 可以輸入excel公式 如 "=SUM(A1, B2)"
a1=datetime.datetime.now().strftime("%Y-%m-%d")#填充當前日期
from openpyxl.styles import Font, Border, Side, PatternFill, colors, Alignment#單元格格式
a1.font=Font(name='等線', size=24, italic=True, underline=True,color=colors.RED, bold=True)#等線 24號 加粗 斜體 下划線 紅色 默認字體11
a1.alignment=Alignment(horizontal='center', vertical='right')#水平居中 豎直居右
left, right, top, bottom = [Side(style='thin', color='000000')] * 4
a1.border = Border(left=left, right=right, top=top, bottom=bottom)#邊框
cell_slice=sheet['coordinate_start':'coordinate_end']
column=sheet['column_letter']
column_slice=sheet['letter_start:letter_end']
row=sheet[row_num]
row_slice=sheet[num_start:num_end]
for row in sheet.iter_rows(min_row=row_num,min_col=col_num,max_row=row_num,max_col=col_num,values_only=False):#指定行 values_only 只有值 沒有坐標
for cell in row:pass
for col in sheet.iter_cols(min_row=row_num,min_col=col_num,max_row=row_num,max_col=col_num,values_only=False):pass#指定列 values_only 只有值 沒有坐標
for row in sheet.rows:
for cell in row:
print(cell.value,cell.coordinate)
for column in sheet.columns:
for cell in column:
print(cell.value,cell.coordinate)
cols_list=list(zip(*rows_list))#矩陣置換 矩陣旋轉 行轉列 列轉行 若某一單元格缺少數據 會被舍棄這一列/行
from openpyxl.drawing.image import Image#插入圖像
sheet.add_image(Image('logo.png'), 'A1')#添加到工作表並錨定在單元格旁邊
import re#正則表達式
#正則表達式常用方法
match_result=re.match(pattern,string,flags)#以pattern正則表達式從string起始位置匹配 只返回一個 無匹配結果返回None
search_result=re.search(pattern,string,flags)#以pattern正則表達式搜索string直到找到一個匹配 只返回一個 無匹配結果返回None
sub_result=re.sub(pattern,substitute,string,count,flags)#以pattern正則表達式搜索string 找到一個匹配 將匹配字符串替換為substitute 無匹配結果返回None 替換count次 默認全部替換 substitute可以是函數
split_result=re.split(pattern,string,count,flags)#以pattern正則表達式匹配string后返回列表
def multiply_2(matched):return str(int(matched.group('value')) * 2)
'A46G8HFD1134'==re.sub(r'(?P<value>\d+)', multiply_2, 'A23G4HFD567')#將字符串中的數字x2
#編譯正則表達式
regex_pattern=re.compile(pattern,flags)#生成一個正則表達式
match_result=regex_pattern.match(string,start_index,end_index)#返回一個match對象
fullmatch_result=regex_pattern.fullmatch(string,start_index,end_index)#整個 string 匹配正則表達式 才返回 否則返回None
match_result.group(index)#返回匹配組 0表示所有分組組成的字符 group從1開始
match_result.start()#返回匹配結果第一個字符在string的索引
match_result.end()#返回匹配結果最后一個字符在string的索引
match_result.span()#返回(start_index,end_index)
search_result=regex_pattern.search(string,start_index,end_index)#返回一個search對象 用法同match對象
findall_result=regex_pattern.findall(string,start_index,end_index)#返回所有匹配組成的列表 匹配所有 如果沒有匹配返回空列表 如果正則表達式分組 返回由分組組成的每個元組組成的列表
finditer_result=regex_pattern.finditer(string,start_index,end_index)#和findall類似 但返回迭代器
sub_result=regex_pattern.sub(substitute,string,count,flags)#將匹配字符串替換為substitute后返回string 無匹配結果返回原string 替換count次 默認全部替換 substitute可以是函數
subn_result=regex_pattern.subn(substitute,string,count,flags)#和 sub類似 但返回元組 (string,count)
escape_result=regex_pattern.escape(pattern)#轉義pattern中具有正則表達式特殊含義的字符
'|'.join(map(re.escape, sorted(['+', '-', '*', '/', '**'], reverse=True)))==r'/|\-|\+|\*\*|\*'
#flags控制匹配方式
re.I#re.IGNORECASE 忽略字母大小寫
re.A#re.ASCII 只匹配ASCII字符
re.DEBUG#顯示編譯時的debug信息
re.L#re.LOCALE 基本沒用 只能對byte樣式有效 由當前語言區域決定 \w, \W, \b, \B 和大小寫敏感匹配
re.M#re.MULTILINE 使^除了匹配整個字符串的起始位置,還匹配換行符\n后面的位置 $除了匹配整個字符串的結束位置,還匹配換行符\n前面的位置
re.S#re.DOTALL 使 . 能夠匹配所有字符
re.X#re.VERBOSE 忽略表達式中的空白 和 #注釋 讓長正則表達式易於理解
verbose_regex = re.compile(
r'''( (\d{3}|\(\d{3}\))? # area code
(\s|-|\.)? # separator
\d{3} # first 3 digits
(\s|-|\.) # separator
\d{4} # last 4 digits
)''',re.X)
re.findall(r'^This.*?line.$', 'This is the first line.\nThis is the second line.\nThis is the third line.', flags=re.M+re.S)==['This is the first line.', 'This is the second line.', 'This is the third line.']#匹配多行文本的每一行
flags=re.M | re.S#另一種flags表示
re.findall(r'(?ms)^This.*?line.$')#另一種flags表示 這種表達方式不需要寫flags 但必須在表達式開頭用(?)聲明 可選參數有(?aiLmsux)
#(?)參數
(str)#分組 索引從1開始 0表示所有組組成的字符串
(?aiLmsx)#字母分別代表 re.A I L M S X 必須在表達式開頭使用
(?:str)#在使用group之類的函數時忽略該組
(?P<group_name>str)#為該組命名 使用groupdict()時鍵為group_name 值為匹配的組
(?P=group_name)#引用(?P<group_name>str)
(?#str)#str會被忽略 當作注釋
(?=str)#只有匹配到str的時候 才會匹配(?=str)前面的表達式
(?!str)#只有沒有匹配到str的時候 才會匹配(?!str)前面的表達式
(?<=str)#在字符串非開始位置匹配以str開頭的字符串 只能是明確的長度 可以理解成 ^str 在字符串非開始位置匹配符合字符
(?<!str)#在字符串非開始位置匹配不以str開頭的字符串 只能是明確的長度 可以理解成 ^str 在字符串非開始位置匹配不符合字符
(?(group_index/group_name)yes-pattern|no-pattern)#如果給定的 group_index 或 group_name 存在,將會嘗試匹配 yes-pattern ,否則就嘗試匹配 no-pattern,no-pattern 可選,也可以被忽略。比如,
r'(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)'#是一個email樣式匹配,將匹配 '<user@host.com>' 或 'user@host.com' ,但不會匹配 '<user@host.com' ,也不會匹配 'user@host.com>'
match_result.group()#返回匹配的整個結果
match_result.group(int)#返回匹配結果的第int組 從1開始
match_result.groups()#返回匹配的所有組
match_result.groupdict()#返回匹配的所有組名和組組成的字典 鍵為組名 值為匹配的組
#匹配模式
r'pattern'#r表示忽略轉義字符 寫正則表達式加上就行
貪婪模式#有多種匹配字符串符合正則表達式 匹配字符串最長的 默認模式
非貪婪模式#有多種匹配字符串符合正則表達式 匹配字符串最短的 用?在正則式結尾修飾 如 .*?
'^str'#只匹配以str開頭的字符串 caret ^必須在$之前 caret before dollar ==abcd
'str$'#只匹配以str結尾的字符串 dollar ^必須在$之前 caret before dollar ==abcd
.#匹配任意一個除了\n的字符 當re.M標記被指定時 則可以匹配包括換行符的任意字符
[str]#匹配在[]的一個字符 如[amk] 匹配 'a' 'm'或'k'
[^str]#不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符
(str)*#匹配0個到n個str 貪婪模式
(str)*?#匹配0個到n個str 非貪婪模式
(str)+#匹配1個到n個str 貪婪模式
(str)+?#匹配1個到n個str 非貪婪模式
(str)?#匹配時str可有可無 貪婪模式
(str)??#匹配時str可有可無 非貪婪模式 即匹配結果為空 ""
(str){ x}#只匹配重復x次的str 例如 (o){2} 不能匹配 "Bob" 中的 "o" 但是能匹配 "food" 中的兩個 o
(str){ x,}#只匹配重復x次到n次的str 例如 o{2,} 不能匹配"Bob"中的"o" 但能匹配 "foooood"中的所有 o "o{1,}" 等價於 "o+" "o{0,}" 則等價於 "o*"
(str){ ,y}#只匹配重復0次到y次的str 例如 o{2,} 不能匹配"Bob"中的"o" 但能匹配 "foooood"中的所有 o "o{1,}" 等價於 "o+" "o{0,}" 則等價於 "o*"
(str){ x, y}#只匹配重復x到y次的str 貪婪模式
(str){ x, y}?#只匹配重復x到y次的str 非貪婪模式 或 str可有可無
a|b#匹配a或b
r'\w' #匹配一個字母數字及下划線 [A-Za-z0-9_] word:3rd-Person
r'\W'#匹配一個非字母數字及下划線 '[^A-Za-z0-9_]'
r'\s'#匹配一個任意空白字符 等價於 [ \f\n\r\t\v]
r'\S'#匹配一個任意非空字符 [^ \f\n\r\t\v]
r'\d'#匹配一個任意數字 等價於 [0-9].
r'\D'#匹配一個任意非數字 [^0-9]
r'\A'#類似^ 但不受re.M控制
r'\Z'#類似$ 但不受re.M控制
r'\z'#匹配一個字符串結束
r'\G'#匹配一個最后匹配完成的位置
'\b'#匹配一個單詞邊界 如 r'\bfoo\b' 匹配 'foo', 'foo.', '(foo)', 'bar foo baz' 但不匹配 'foobar' 或者 'foo3'
r'\B'#匹配非單詞邊界 如 r'py\B' 匹配 'python', 'py3', 'py2', 但不匹配 'py', 'py.', 或者 'py!'. \B 是 \b 的取非
'\n'#匹配一個換行符
'\t'#匹配一個制表符
'\1'-'\99'#第1-99個分組的內容 表達式自身也可以引用
re.compile(r'Agent (\w)\w*').sub(r'\1****', 'Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a spy.')=='A**** told C**** that E**** knew B**** was a spy.'
[0-9]#匹配任何數字 類似於 [0123456789]
[a-z] #匹配任何小寫字母
[A-Z]#匹配任何大寫字母
[a-zA-Z0-9]#匹配任何字母及數字
[^aeiou]#除了aeiou字母以外的所有字符
[^0-9]#匹配除了數字外的字符
r'\d(.*) are (.*?) .*'
r 表示忽略轉義字符
(.*) 第一個匹配分組,.* 代表匹配除之外的所有長度的字符
(.*?) 第二個匹配分組,.*? 后面多個問號,代表非貪婪模式,只匹配符合條件的最少字符
re.compile(r'<.*?>').search('<To serve man> for dinner.>').group()=='<To serve man>'
re.compile(r'<.*>').search('<To serve man> for dinner.>').group()=='<To serve man> for dinner.>'
#常用正則表達式 https://www.cnblogs.com/magicking/p/8986869.html
pyInstaller #python打包 .exe程序 在別的電腦有幾率exe出錯 原因是別的電腦缺少相關運行庫 過幾年等pyInstaller自己更新打包算法
#安裝打包模塊之前 先升級pip
#GUI開發選用tkinter會減少很多麻煩事
簡單程序打包
.py文件儲存目錄 打開cmd輸入以下任意代碼
#用於簡單測試程序 單個.exe文件 保留打包過程產生的日志和緩存
pyinstaller -F main_script.py
#-F 只生成一個exe文件 如果有多個.py文件 或自帶資源 不能帶該參數 文件復雜不建議使用該參數
#最終程序 目錄形式 不含終端 含程序圖標刪除打包過程產生的日志和緩存
pyinstaller -D -w -i icon.ico --clean main_script.py
pyinstaller -F -w -i icon.ico --clean main_script.py --upx-dir=D:\softwares\upx-3.96-win64\upx.exe
#-D 打包成一個目錄的形式 為打包的默認形式 可以不加
#-w 執行.exe文件時隱藏控制台 建議只有在已經設置了GUI時才帶這個參數 只對windows有效
#-c 執行.exe文件時顯示控制台 默認會顯示 可以不加
#-i 替換程序圖標
#icon.ico 程序同級目錄里的程序圖標
#--clean 在打包前清除pyinstaller緩存
#--debug=all 顯示所有程序診斷信息
#main_script.py 將要打包的程序 如果有多個py文件 main_script是程序的主程序
#--upx-dir=path upx的安裝目錄 upx用於壓縮exe https://upx.github.io
#打包完成后在py目錄中 spec和build是打包過程產生的數據和日志文件 pycache是緩存文件 dist是程序文件
#打包結束除了dist文件都可以刪除 dist是.exe所在目錄 如果程序使用了自帶資源 要把自帶資源放在.exe同級目錄 也就是dist內 dist可以重命名
例如使用了icon.ico 需要放在exe同級目錄
復雜程序打包
pip install pipenv#cmd輸入 安裝pip虛擬環境 直接打包 程序會很大 在虛擬環境進行打包 如果對文件大小不在意 可以直接跳過虛擬環境設置部分
選擇一個目錄作為虛擬環境目錄 在該目錄下 cmd 創建虛擬環境
pipenv install --python 3.9.5
#選擇的目錄是 Python_Virtual_Env python版本要符合使用的版本
#pipenv安裝packages會生成一個Pipfile.lock的文件 這個文件主要是關於所下載的packages的一些信息
打開虛擬環境中的Pipfile
修改url = "https://pypi.tuna.tsinghua.edu.cn/simple/"#包下載地址替換為清華源
pipenv shell#cmd 激活虛擬環境 每次安裝包都要先輸入
exit#cmd 退出虛擬環境
#若package安裝失敗 將Pipfile.lock刪除 然后在控制台中通過pipenv lock來生成新的Pipfile.lock
在虛擬環境下安裝需要打包的程序的依賴的庫#模塊之間用空格分開
pip install pywin32 pyinstaller
在虛擬環境下進行打包
在程序同級目錄 打開cmd輸入
pyi-makespec -w main_script.py
會生成一個對於 main_script.py的 main_script.spec文件#main_script.py 是將要打包的主程序文件
#spec文件中主要包含 Analysis PYZ EXE COLLECT
#Analysis以py文件為輸入 它會分析py文件的依賴模塊 並生成相應的信息
#PYZ是一個.pyz的壓縮包 包含程序運行需要的所有依賴
#EXE根據上面兩項生成
#COLLECT生成其他部分的輸出文件夾 COLLECT也可以沒有
#官方spec說明 https://pyinstaller.readthedocs.io/en/v4.5.1/spec-files.html#using-spec-files
打開 .spec文件 依照下列代碼進行內容修改 注釋可以不用刪
# -*- mode: python ; coding: utf-8 -*-
#指定utf-8編碼
#出錯 提示RecursionError: maximum recursion depth exceeded 用下面兩行代碼 一般可以不管 5000可以替換成其他數值
#import sys
#sys.setrecursionlimit(5000)
block_cipher = None
a = Analysis(['D:\\script_folder1\\script_folder2\\main_script.py',
'D:\\script_folder1\\script_folder2\\aux_script1.py',
'D:\\script_folder1\\script_folder2\\aux_script1.py'],
#修改為需要打包的.py文件 完整路徑 程序所有相關的.py文件都要寫入 注意必須是\\
pathex=['D:\\script_folder1\\script_folder2',
'D:\\python39\\Lib\\site-packages\\used_package_folder1',
'D:\\python39\\Lib\\site-packages\\used_package_folder2'],
#修改為.py文件import的模塊所在文件夾 包括python模塊 三方模塊 自己寫的模塊 site-packages文件夾里的才是三方模塊 注意必須是\\ 完整路徑 如果程序運行出錯 提示缺少什么就補相應的文件夾
binaries=[('C:\\Windows\\SysWOW64\\api-ms-win-core-path-l1-1-0.dll','.')],#所有二進制資源儲存的文件夾或文件 如dll 動態庫 一般不用管 為空列表 列表元素格式和datas一樣
#打包后的exe在沒有Python環境上運行可能提示缺少api-ms-win-core-path-l1-1-0.dll
#參考 http://www.xitongzhijia.net/soft/201409.html 下載該dll
#將該dll復制一份到Python根目錄
#將該dll復制一份到Windows\SysWOW64
#將該dll復制一份到Windows\System32\downlevel
datas=[('D:\\script_folder1\\script_folder2\\images\\role_images','images\\role_images'),
('D:\\script_folder1\\script_folder2\\sound','sound'),
('D:\\script_folder1\\script_folder2\\*.txt','.'),
('D:\\script_folder1\\script_folder2\\icon.ico','.')],#所有資源儲存的文件夾或文件 如程序內用到的exe圖標 聲音 圖片 數據文件等 元組格式為(資源文件儲存路徑,打包后相對exe的路徑) . 表示exe所在目錄 *表示匹配任意多個字符
hiddenimports=['module_name1','module_name2'],#打包后執行程序時出現類似No Module named xxx 在此添加程序中引入的模塊名稱 一般設置為空列表 []
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=['module_name1','module_name2'],#打包時不打包的模塊 一般設置為空列表 []
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
exclude_binaries=True,
name='exe_name',
#name為.exe名
debug=False,#調試測bug的時候可以改為True
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,#True顯示控制台 False不顯示
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='D:\\script_folder1\\script_folder2\\main_script.ico'#exe程序圖標 必須是ico格式 完整路徑 注意是\\
)
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='exe_name')#name為.exe名
修改完成后 cmd輸入
pyinstaller -D --clean main_script.spec
#生成的build文件可以刪除 __pycache__ .spec最好不刪 exe在dist內 若有自定義資源 或三方庫 要復制到和exe同級目錄
#打包后的程序還是很大 用upx對exe文件進行壓縮 https://upx.github.io
在程序目錄 cmd輸入#upx_file是upx儲存目錄
pyinstaller --upx-dir upx_file --clean main.py
if __name__ == '__main__':
multiprocessing.freeze_support()#如果調用多線程 必須這么寫 否則運行exe會顯示 Failed to execute script pyi_rth_multiprocessing
#以下備注不確定是否有效
#
if __name__ == '__main__':#需要打包的程序不要使用該代碼 否則可能出錯
#需要打包的程序 使用from..import... 減少程序大小
#程序中使用的三方庫要復制到程序同目錄 否則可能出錯
#
#Python>=3.5開發的程序 在非Windows10使用 程序可能會出現 Visual C++ run-time .dlls的錯誤 若遇到此問題 解決方法之一是在win7上開發程序 其他方法略
#更多見 https://blog.csdn.net/weixin_42052836/article/details/82315118?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.essearch_pc_relevant&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.essearch_pc_relevant
cx_freeze#另一種打包模塊
#https://www.jianshu.com/p/c029574187d2