主頁 > 後端開發 > python常用模塊

python常用模塊

2020-09-18 07:10:17 後端開發

常用模塊:

一、time模塊

二、datetime模塊

三、sys 模塊

四、os 模塊

五、random 模塊

六、shutil 模塊

七、json, pickle , shelve模塊

八、xml 模塊

九、configparer模塊

十、hashlib模塊

十一、re模塊

十二、logging模塊

十三、subprocess

 

一、time模塊

import time

# s = time.time()
# print(s)
# time.sleep(2)

# 拿到format string的方式
# print(time.ctime(s))   # time.ctime(float) ----> format string in local time
# print(time.asctime(time.localtime(s)))    # time.asctime(tuple) ----> format string in local time
# print(time.asctime())    # 如果不傳值,默認的就會用當前的時間戳
# print(time.ctime())    # 如果不傳值,默認的就會用當前的struct time
# print(time.localtime())

# print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))    # 按照給定的格式 將 tuple---> string, strptime  是 string parse time 的縮寫,就是將字串決議成元組的意思,
 

Commonly used format codes:

%Y Year with century as a decimal number.
%m Month as a decimal number [01,12].
%d Day of the month as a decimal number [01,31].
%H Hour (24-hour clock) as a decimal number [00,23].
%M Minute as a decimal number [00,59].
%S Second as a decimal number [00,61].
%z Time zone offset from UTC.
%a Locale's abbreviated weekday name.
%A Locale's full weekday name.
%b Locale's abbreviated month name.
%B Locale's full month name.
%c Locale's appropriate date and time representation.
%I Hour (12-hour clock) as a decimal number [01,12].
%p Locale's equivalent of either AM or PM.



# 拿到時間戳 float 型別
# tu = time.localtime()
# print(tu)
# s = time.mktime(tu)    # time.mktime() 將 tuple----> float
# print(time.time())

# 拿到struct time 型別
# s = time.time()
# print(time.localtime(s))   # 北京時間 接受float ---> tuple
# print(time.gmtime(s))   # 天文臺時間 接受float ---> tuple

The other representation is a tuple of 9 integers giving local time.
The tuple items are:
year (including century, e.g. 1998)
month (1-12)
day (1-31)
hours (0-23)
minutes (0-59)
seconds (0-59)
weekday (0-6, Monday is 0)
Julian day (day in the year, 1-366)
DST (Daylight Savings Time) flag (-1, 0 or 1)
If the DST flag is 0, the time is given in the regular time zone;
if it is 1, the time is given in the DST time zone;
if it is -1, mktime() should guess based on the date and time.



# print(time.strptime(time.ctime()))   # 接受 string ---> tuple, strftime 是 string format time 的縮寫  就是轉成字串時間的意思
# print(time.strptime(time.asctime()))   # 接受 string ---> tuple

 

 

 

二、datetime模塊

在python檔案中,time是歸類在常規作業系統服務中,它提供的功能更加接近于作業系統層面,其所能表述的日期范圍被限定在1970-2038之間,如果需要表述范圍之外的日期,可能需要考慮使用datetime模塊更好,

datetime比time高級了不少,可以理解為datetime基于time進行了封裝,提供了更多實用的函式,主要包含一下幾類:

    • timedelta:主要用于計算時間跨度
    • tzinfo:時區相關
    • time:只關注時間
    • date:只關注日期
    • datetime:同時有時間和日期

在實際使用中,用得比較多的是datetime.datetime和datetime.timedelta,另外兩個datetime.date和datetime.time實際使用和datetime.datetime并無太大差別,datetime.datetime 主要會有以下屬性及常用方法:

  datetime.datetime.ctime()   將datetime.datetime型別轉化成str型別,輸出:Sun Jul 28 15:47:51 2019

  datetime.datetime.now():回傳當前系統時間:2019-07-28 15:42:24.765625

  datetime.datetime.now().date():回傳當前日期時間的日期部分:2019-07-28

  datetime.datetime.now().time():回傳當前日期時間的時間部分:15:42:24.750000

  datetime.datetime.fromtimestamp() 

  datetime.datetime.replace()

  datetime.datetime.strftime():由日期格式轉化為字串格式

    datetime.datetime.now().strftime('%b-%d-%Y %H:%M:%S')
      'Apr-16-2017 21:01:35'

  datetime.datetime.strptime():由字串格式轉化為日期格式

    datetime.datetime.strptime('Apr-16-2017 21:01:35', '%b-%d-%Y %H:%M:%S')
      2017-04-16 21:01:35

 

  除了實體本身具有的方法,類本身也提供了很多好用的方法:

  1. datetime.strptime(date_string,format): 給定時間格式決議字串
  2. datetime.now([tz]):當前時間默認 localtime
  3. datetime.today():當前時間

 

  datetime.timedelta用來計算兩個datetime.datetime或者datetime.date型別之間的時間差,

  >>> a=datetime.datetime.now()
  >>> b=datetime.datetime.now()
  >>> a
  datetime.datetime(2017, 4, 16, 21, 21, 20, 871000)
  >>> b
  datetime.datetime(2017, 4, 16, 21, 21, 29, 603000)

  >>> b-a
  datetime.timedelta(0, 8, 732000)
  >>> (b-a).seconds
  8

  或者

  time1 = datetime.datetime(2016, 10, 20)
  time2 = datetime.datetime(2015, 11, 2)

  """計算天數差值"""
  print(time1-time2).days

  """計算兩個日期之間相隔的秒數"""
  print (time1-time2).total_seconds()

 

 

import datetime, time   # 用于時間加減

print(datetime.datetime.now())  # 回傳 2020-08-01 16:15:58.512076
print(datetime.date.fromtimestamp(time.time()))  # 時間戳直接轉成日期格式 2019-01-01

print(datetime.datetime.now() + datetime.timedelta(3))  # 當前時間+3天  2019-01-04 00:56:58.771296
print(datetime.datetime.now() + datetime.timedelta(-3))  # 當前時間-3天 2018-12-29 00:56:58.771296
print(datetime.datetime.now() + datetime.timedelta(hours=3))  # 當前時間+3小時  2019-01-01 03:56:58.771296
print(datetime.datetime.now() + datetime.timedelta(minutes=30))  # 當前時間+30分  2019-01-01 01:26:58.771296

c_time = datetime.datetime.now()
print(c_time.replace(minute=3, hour=2))  # 時間替換  2019-01-01 02:03:58.771296

 

 列印進度條

import time


def progress(percent):
'''列印進度條'''
if percent > 1:
percent = 1
res = int(50 * percent) * 'I'
print('\r[%-50s] %d%%' % (res, int(100 * percent)), end='')



recv_size=0
total_size=1025

while recv_size < total_size:
time.sleep(0.01) # 下載了1024個位元組的資料
recv_size+=1024 # recv_size=2048

# 列印進度條
percent = recv_size / total_size # 1024 / 333333
progress(percent)

三、sys 模塊

 

import sys
sys.argv   #在命令列引數是一個空串列,在其他中第一個串列元素中程式本身的路徑
sys.exit(0) #退出程式,正常退出時exit(0)
sys.version  #獲取python解釋程式的版本資訊
sys.path #回傳模塊的搜索路徑,初始化時使用python PATH環境變數的值
sys.platform #回傳作業系統平臺的名稱
sys.stdin    #輸入相關 standard input 標準輸入
sys.stdout  #輸出相關 standard output 標注輸出
sys.stderror #錯誤相關

sys.getrecursionlimit() #獲取最大遞回層數 1000
sys.setrecursionlimit(5000) #設定最大遞回層數

 

四、os 模塊

控制作業系統

os.getcwd() 獲取當前作業目錄,即當前python腳本作業的目錄路徑
os.chdir("dirname") 改變當前腳本作業目錄;相當于shell下cd
os.curdir 回傳當前目錄: ('.')
os.pardir 獲取當前目錄的父目錄字串名:('..')
os.makedirs('dirname1/dirname2') 可生成多層遞回目錄
os.removedirs('dirname1') 若目錄為空,則洗掉,并遞回到上一級目錄,如若也為空,則洗掉,依此類推
os.mkdir('dirname') 生成單級目錄;相當于shell中mkdir dirname
os.rmdir('dirname') 洗掉單級空目錄,若目錄不為空則無法洗掉,報錯;相當于shell中rmdir dirname
os.listdir('dirname') 列出指定目錄下的所有檔案和子目錄,包括隱藏檔案,并以串列方式列印
os.remove() 洗掉一個檔案
os.rename("oldname","newname") 重命名檔案/目錄
os.stat('path/filename') 獲取檔案/目錄資訊
os.sep 輸出作業系統特定的路徑分隔符,win下為"\\",Linux下為"/"
os.linesep 輸出當前平臺使用的行終止符,win下為"\t\n",Linux下為"\n"
os.pathsep 輸出用于分割檔案路徑的字串 win下為;,Linux下為:
os.name 輸出字串指示當前使用平臺,win->'nt'; Linux->'posix'
os.system("bash command") 運行shell命令,直接顯示
os.environ 獲取系統環境變數
os.path.abspath(path) 回傳path規范化的絕對路徑
os.path.split(path) 將path分割成目錄和檔案名二元組回傳
os.path.dirname(path) 回傳path的目錄,其實就是os.path.split(path)的第一個元素
os.path.basename(path) 回傳path最后的檔案名,如何path以/或\結尾,那么就會回傳空值,即os.path.split(path)的第二個元素
os.path.exists(path) 如果path存在,回傳True;如果path不存在,回傳False
os.path.isabs(path) 如果path是絕對路徑,回傳True
os.path.isfile(path) 如果path是一個存在的檔案,回傳True,否則回傳False
os.path.isdir(path) 如果path是一個存在的目錄,則回傳True,否則回傳False
os.path.join(path1[, path2[, ...]]) 將多個路徑組合后回傳,第一個絕對路徑之前的引數將被忽略
print(os.path.join("D:\\python\\wwww","aaa")) #做路徑拼接用的 #D:\python\wwww\aaa
print(os.path.join(r"D:\python\wwww","aaa")) #做路徑拼接用的 #D:\python\wwww\aaa
os.path.getatime(path) 回傳path所指向的檔案或者目錄的最后存取時間
os.path.getmtime(path) 回傳path所指向的檔案或者目錄的最后修改時間
os.path.getsize(path) 回傳path的大小
在Linux和Mac平臺上,該函式會原樣回傳path,在windows平臺上會將路徑中所有字符轉換為小寫,并將所有斜杠轉換為反斜杠,
>>> os.path.normcase('c:/windows\\system32\\')
'c:\\windows\\system32\\'


規范化路徑,如..和/
>>> os.path.normpath('c://windows\\System32\\../Temp/')
'c:\\windows\\Temp'

>>> a='/Users/jieli/test1/\\\a1/\\\\aa.py/../..'
>>> print(os.path.normpath(a))
/Users/jieli/test1


os路徑處理
#方式一:推薦使用
import os
#具體應用
import os,sys
possible_topdir = os.path.normpath(os.path.join(
os.path.abspath(__file__),
os.pardir, #上一級
os.pardir,
os.pardir
))
sys.path.insert(0,possible_topdir)


#方式二:不推薦使用
os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

 

五、random 模塊

# 隨機生成
import random

print(random.random()) # (0,1)----float 大于0且小于1之間的小數
print(random.randint(1, 3)) # [1,3] 大于等于1且小于等于3之間的整數
print(random.randrange(1, 3)) # [1,3) 大于等于1且小于3之間的整數
print(random.choice([1, '23', [4, 5]])) # 1或者23或者[4,5]
print(random.sample([1, '23', [4, 5]], 2)) # 串列元素任意2個組合
print(random.uniform(1, 3)) # 大于1小于3的小數,如1.927109612082716

item = [1, 3, 5, 7, 9]
random.shuffle(item) # 打亂item的順序,相當于"洗牌"
print(item)

# 隨機生成驗證碼
import random

def make_code(n):
  res = ''
  for i in range(n):
    alf = chr(random.randint(65, 90))
    num = str(random.randint(0, 9))
    res += random.choice([alf, num])
  return res


print(make_code(6))

------------------------------------------------------------->
import random, string

source = string.digits + string.ascii_lowercase + string.ascii_uppercase + string.ascii_letters
print(source)
# 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
print("".join(random.sample(source, 6)))

六、shutil 模塊

高級的 檔案,檔案夾,壓縮包處理模塊

shutil.copyfileobj(fsrc, fdst[, length])
將檔案內容拷貝到另一個檔案中

shutil.copyfile(src, dst)
拷貝檔案,

shutil.copymode(src, dst)
僅拷貝權限,內容、組、用戶均不變

shutil.copystat(src, dst)
僅拷貝狀態的資訊,包括:mode bits, atime, mtime, flags

shutil.copy(src, dst)
拷貝檔案和權限

shutil.copy2(src, dst)
拷貝檔案和狀態資訊

shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
遞回的去拷貝檔案夾

shutil.move(src, dst)
遞回的去移動檔案,它類似mv命令,其實就是重命名,
"""

shutil.copyfileobj(open('xmltest.xml','r'), open('new.xml', 'w'))
shutil.copyfile('b.txt', 'bnew.txt')#目標檔案無需存在
shutil.copymode('f1.log', 'f2.log') #目標檔案必須存在
shutil.copystat('f1.log', 'f2.log') #目標檔案必須存在
shutil.copy('f1.log', 'f2.log')
shutil.copy2('f1.log', 'f2.log')
shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目標目錄不能存在,注意對folder2目錄父級目錄要有可寫權限,ignore的意思是排除

'''
通常的拷貝都把軟連接拷貝成硬鏈接,即對待軟連接來說,創建新的檔案
'''
#拷貝軟連接
shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))

shutil.move('folder1', 'folder3')

"""
shutil.make_archive(base_name, format,...)
創建壓縮包并回傳檔案路徑,例如:zip、tar

base_name: 壓縮包的檔案名,也可以是壓縮包的路徑,只是檔案名時,則保存至當前目錄,否則保存至指定路徑,
      如 data_bak =>保存至當前路徑
      如:/tmp/data_bak =>保存至/tmp/
format: 壓縮包種類,“zip”, “tar”, “bztar”,“gztar”
root_dir: 要壓縮的檔案夾路徑(默認當前目錄)
owner: 用戶,默認當前用戶
group: 組,默認當前組
logger: 用于記錄日志,通常是logging.Logger物件
"""

# 將 /data 下的檔案打包放置當前程式目錄
import shutil
ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
# 將 /data下的檔案打包放置 /tmp/目錄
import shutil
ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')


#shutil 對壓縮包的處理是呼叫 ZipFile 和 TarFile 兩個模塊來進行的,詳細:

#zipfile壓縮解壓縮
import zipfile
# 壓縮
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data')
z.close()

# 解壓
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall(path='.')
z.close()


#tarfile壓縮解壓縮
import tarfile

# 壓縮
t=tarfile.open('/tmp/egon.tar','w')
t.add('/test1/a.py',arcname='a.bak')
t.add('/test1/b.py',arcname='b.bak')
t.close()

# 解壓
t=tarfile.open('/tmp/egon.tar','r')
t.extractall('/egon')
t.close()

 

 

七、json, pickle 模塊

1.什么是序列化?

序列化指的是把記憶體的資料型別轉換成一個特定的格式的內容

該格式的內容可以用于存盤或者傳輸給其他平臺使用

與序列化想對應的逆操作是返序列化,

 

記憶體中的資料型別  -----》 序列化 ------》特定的格式 (json 或者pickle格式)

記憶體中的資料型別《----- 反序列化《------ 特定的格式 (json 或者pickle格式)

 

{‘a':111}  -----》 序列化 str({‘a':111}) ------》"{‘a':111} "

{‘a':111}《----- 反序列化 eval("{‘a':111} ")《------ "{‘a':111} "

 

3.為何要有序列化?

序列化得到結果---》特定的格式的內容有兩種用途 (可以用于存盤,可以傳輸給其他平臺使用)

pickle 只能識別Python的資料格式,如果只是存檔的話,建議使用pickle

json是通用的,json格式兼容的是所有語言通用的資料型別,不能識別某一語言的所獨有的型別,跨平臺資料互動的話可用json

  • JSON表示的物件就是標準的JavaScript語言的物件,JSON和Python內置的資料型別對應如下:

4.如何實作序列化

import json
# 序列化
json_res=json.dumps([1,'aaa',True,False])
# print(json_res,type(json_res)) # "[1, "aaa", true, false]"

# 反序列化
l=json.loads(json_res)
print(l,type(l))

 

# 序列化的結果寫入檔案的復雜方法
json_res=json.dumps([1,'aaa',True,False])
with open('test.json',mode='wt',encoding='utf-8') as f:
f.write(json_res)

# 將序列化的結果寫入檔案的簡單方法
with open('test.json',mode='wt',encoding='utf-8') as f:
json.dump([1,'aaa',True,False],f)


# 從檔案讀取json格式的字串進行反序列化操作的復雜方法
with open('test.json',mode='rt',encoding='utf-8') as f:
json_res=f.read()
l=json.loads(json_res)
print(l,type(l))

# 從檔案讀取json格式的字串進行反序列化操作的簡單方法
with open('test.json',mode='rt',encoding='utf-8') as f:
l=json.load(f)
print(l,type(l))
# 4、猴子補丁
# 在入口處打猴子補丁
import json
import ujson

def monkey_patch_json():
json.__name__ = 'ujson'
json.dumps = ujson.dumps # 在自己寫好的 ujson 模塊中,有更好的dumps 方法,以后呼叫json.dumps 其實就是在參考ujson.dump
json.loads = ujson.loads

monkey_patch_json() # 在入口檔案出運行
print(json.loads)
json.loads = 'bbb'
print(json.loads)


import pickle
pickle 和 json 用法一樣


dic = {'name': 'tom', 'age': 23, 'sex': 'male'}
print(type(dic)) # <class 'dict'>

j = pickle.dumps(dic)
print(type(j)) # <class 'bytes'>

f = open('序列化物件_pickle', 'wb') # 注意是w是寫入str,wb是寫入bytes,j是'bytes'
f.write(j) #-等價于pickle.dump(dic,f)

f.close()

# 反序列化
import pickle
f = open('序列化物件_pickle', 'rb')
data = https://www.cnblogs.com/Teyisang/p/pickle.loads(f.read()) # 等價于data=pickle.load(f)
print(data['age'])

 

shelve模塊比pickle模塊簡單,只有一個open函式,回傳類似字典的物件,可讀可寫;key必須為字串,而值可以是python所支持的

import shelve
f=shelve.open(r'sheve.txt')
#存
# f['stu1_info']={'name':'rose','age':18,'hobby':['sing','talk','swim']}
# f['stu2_info']={'name':'tom','age':53}
#取
print(f['stu1_info']['hobby'])
f.close()

 

八、xml 模塊

xml是實作不同語言或程式之間進行資料交換的協議,跟json差不多,但json使用起來更簡單,不過,古時候,在json還沒誕生的黑暗年代,大家只能選擇用xml呀,至今很多傳統公司如金融行業的很多系統的介面還主要是xml,

xml的格式如下,就是通過<>節點來區別資料結構的:

<?xml version="1.0"?>
<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor name="Austria" direction="E"/>
        <neighbor name="Switzerland" direction="W"/>
    </country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor name="Malaysia" direction="N"/>
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor name="Costa Rica" direction="W"/>
        <neighbor name="Colombia" direction="E"/>
    </country>
</data>

xml資料

xml協議在各個語言里的都 是支持的,在python中可以用以下模塊操作xml:


# print(root.iter('year')) #全文搜索
# print(root.find('country')) #在root的子節點找,只找一個
# print(root.findall('country')) #在root的子節點找,找所有


import xml.etree.ElementTree as ET
 
tree = ET.parse("xmltest.xml")
root = tree.getroot()
print(root.tag)
 
#遍歷xml檔案
for child in root:
    print('========>',child.tag,child.attrib,child.attrib['name'])
    for i in child:
        print(i.tag,i.attrib,i.text)
 
#只遍歷year 節點
for node in root.iter('year'):
    print(node.tag,node.text)
#---------------------------------------

import xml.etree.ElementTree as ET
 
tree = ET.parse("xmltest.xml")
root = tree.getroot()
 
#修改
for node in root.iter('year'):
    new_year=int(node.text)+1
    node.text=str(new_year)
    node.set('updated','yes')
    node.set('version','1.0')
tree.write('test.xml')
 
 
#洗掉node
for country in root.findall('country'):
   rank = int(country.find('rank').text)
   if rank > 50:
     root.remove(country)
 
tree.write('output.xml')
View Code
#在country內添加(append)節點year2
import xml.etree.ElementTree as ET
tree = ET.parse("a.xml")
root=tree.getroot()
for country in root.findall('country'):
    for year in country.findall('year'):
        if int(year.text) > 2000:
            year2=ET.Element('year2')
            year2.text='新年'
            year2.attrib={'update':'yes'}
            country.append(year2) #往country節點下添加子節點

tree.write('a.xml.swap')
View Code

自己創建xml檔案:

import xml.etree.ElementTree as ET
 
 
new_xml = ET.Element("namelist")
name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
age = ET.SubElement(name,"age",attrib={"checked":"no"})
sex = ET.SubElement(name,"sex")
sex.text = '33'
name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
age = ET.SubElement(name2,"age")
age.text = '19'
 
et = ET.ElementTree(new_xml) #生成檔案物件
et.write("test.xml", encoding="utf-8",xml_declaration=True)
 
ET.dump(new_xml) #列印生成的格式
View Code

 

xml教程的:點擊

 

九、configparser 模塊

configparser用于處理特定格式的檔案,本質上是利用open來操作檔案,主要用于組態檔分析用的

該模塊適用于組態檔的格式與windows ini檔案類似,可以包含一個或多個節(section),每個節可以有多個引數(鍵=值),

# 注釋1
; 注釋2

[section1]
k1 = v1
k2:v2
user=egon
age=18
is_admin=true
salary=31

[section2]
k1 = v1
組態檔
"""
讀取
"""
import configparser

config = configparser.ConfigParser()
config.read('a.cfg')

# 查看所有的標題
res = config.sections()  # ['section1', 'section2']
print(res)

# 查看標題section1下所有key=value的key
options = config.options('section1')
print(options)  # ['k1', 'k2', 'user', 'age', 'is_admin', 'salary']

# 查看標題section1下所有key=value的(key,value)格式
item_list = config.items('section1')
print(
    item_list)  # [('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')]

# 查看標題section1下user的值=>字串格式
val = config.get('section1', 'user')
print(val)  # egon

# 查看標題section1下age的值=>整數格式
val1 = config.getint('section1', 'age')
print(val1)  # 18

# 查看標題section1下is_admin的值=>布林值格式
val2 = config.getboolean('section1', 'is_admin')
print(val2)  # True

# 查看標題section1下salary的值=>浮點型格式
val3 = config.getfloat('section1', 'salary')
print(val3)  # 31.0

"""
改寫
"""
import configparser

config = configparser.ConfigParser()
config.read('a.cfg', encoding='utf-8')

# 洗掉整個標題section2
config.remove_section('section2')

# 洗掉標題section1下的某個k1和k2
config.remove_option('section1', 'k1')
config.remove_option('section1', 'k2')

# 判斷是否存在某個標題
print(config.has_section('section1'))

# 判斷標題section1下是否有user
print(config.has_option('section1', ''))

# 添加一個標題
config.add_section('egon')

# 在標題egon下添加name=egon,age=18的配置
config.set('egon', 'name', 'egon')
# config.set('egon','age',18) #報錯,必須是字串


# 最后將修改的內容寫入檔案,完成最終的修改
config.write(open('a.cfg', 'w'))

"""
基于上述方法添加一個ini檔案
"""
import configparser

config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
                     'Compression': 'yes',
                     'CompressionLevel': '9'}

config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'  # mutates the parser
topsecret['ForwardX11'] = 'no'  # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
    config.write(configfile)
讀取,改寫,新建

 

import configparser
  
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
                      'Compression': 'yes',
                     'CompressionLevel': '9'}
  
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022'     # mutates the parser
topsecret['ForwardX11'] = 'no'  # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
   config.write(configfile)
基于上述方法添加一個ini檔案

 

十、hashlib 模塊

hash是一種演算法(3.x里代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 演算法),該演算法接受傳入的內容,經過運算得到一串hash值

hash值的特點是

  • 只要傳入的內容一樣,得到的hash值必然一樣
  • 不能由hash值返解成內容,不應該在網路傳輸明文密碼
  • 只要使用的hash演算法不變,無論校驗的內容有多大,得到的hash值長度是固定的

1、演算法介紹

Python的hashlib提供了常見的摘要演算法,如MD5,SHA1等等,

什么是摘要演算法呢?摘要演算法又稱哈希演算法、散列演算法,它通過一個函式,把任意長度的資料轉換為一個長度固定的資料串(通常用16進制的字串表示),

摘要演算法就是通過摘要函式f()對任意長度的資料data計算出固定長度的摘要digest,目的是為了發現原始資料是否被人篡改過,

摘要演算法之所以能指出資料是否被篡改過,就是因為摘要函式是一個單向函式,計算f(data)很容易,但通過digest反推data卻非常困難,而且,對原始資料做一個bit的修改,都會導致計算出的摘要完全不同,

MD5是最常見的摘要演算法,速度很快,生成結果是固定的128 bit位元組,通常用一個32位的16進制字串表示,另一種常見的摘要演算法是SHA1,呼叫SHA1和呼叫MD5完全類似:

SHA1的結果是160 bit位元組,通常用一個40位的16進制字串表示,比SHA1更安全的演算法是SHA256和SHA512,不過越安全的演算法越慢,而且摘要長度更長,

2、摘要演算法應用

任何允許用戶登錄的網站都會存盤用戶登錄的用戶名和口令,如何存盤用戶名和口令呢?方法是存到資料庫表中:

name    | password
--------+----------
michael | 123456
bob     | abc999
alice   | alice2008

如果以明文保存用戶口令,如果資料庫泄露,所有用戶的口令就落入黑客的手里,此外,網站運維人員是可以訪問資料庫的,也就是能獲取到所有用戶的口令,正確的保存口令的方式是不存盤用戶的明文口令,而是存盤用戶口令的摘要,比如MD5:

username | password
---------+---------------------------------
michael  | e10adc3949ba59abbe56e057f20f883e
bob      | 878ef96e86145580c38c87f0410ad153
alice    | 99b1c2188db85afee403b1536010c2c9

考慮這么個情況,很多用戶喜歡用123456,888888,password這些簡單的口令,于是,黑客可以事先計算出這些常用口令的MD5值,得到一個反推表:

'e10adc3949ba59abbe56e057f20f883e': '123456'
'21218cca77804d2ba1922c33e0151105': '888888'
'5f4dcc3b5aa765d61d8327deb882cf99': 'password'

這樣,無需破解,只需要對比資料庫的MD5,黑客就獲得了使用常用口令的用戶賬號,

對于用戶來講,當然不要使用過于簡單的口令,但是,我們能否在程式設計上對簡單口令加強保護呢?

由于常用口令的MD5值很容易被計算出來,所以,要確保存盤的用戶口令不是那些已經被計算出來的常用口令的MD5,這一方法通過對原始口令加一個復雜字串來實作,俗稱“加鹽”:

hashlib.md5("salt".encode("utf8"))

經過Salt處理的MD5口令,只要Salt不被黑客知道,即使用戶輸入簡單口令,也很難通過MD5反推明文口令,

但是如果有兩個用戶都使用了相同的簡單口令比如123456,在資料庫中,將存盤兩條相同的MD5值,這說明這兩個用戶的口令是一樣的,有沒有辦法讓使用相同口令的用戶存盤不同的MD5呢?

如果假定用戶無法修改登錄名,就可以通過把登錄名作為Salt的一部分來計算MD5,從而實作相同口令的用戶也存盤不同的MD5,

摘要演算法在很多地方都有廣泛的應用,要注意摘要演算法不是加密演算法,不能用于加密(因為無法通過摘要反推明文),只能用于防篡改,但是它的單向計算特性決定了可以在不存盤明文口令的情況下驗證用戶口令,

 

'''
注意:把一段很長的資料update多次,與一次update這段長資料,得到的結果一樣
'''
import hashlib
m = hashlib.md5()  # m=hashlib.sha256()
m.update('hello'.encode('utf8'))
print(m.hexdigest())  # 5d41402abc4b2a76b9719d911017c592
m.update('world'.encode('utf8'))
print(m.hexdigest())  # fc5e038d38a57032085441e7fe7010b0
m2 = hashlib.md5()
m2.update('helloworld'.encode('utf8'))
print(m2.hexdigest())  # fc5e038d38a57032085441e7fe7010b0

hashlib
hashlib
 def get_md5_doc(file, size):
        obj = hashlib.md5('+Yan'.encode('utf8')) # 密碼加鹽
        with open(file, 'rb') as f:
            while size:
                content = f.read(10)
                obj.update(content)
                size -= len(content)
        return obj.hexdigest()
md5對檔案加密

 

 

 

 

十一、re 模塊

正則運算式是用來---->匹配 字串
字串提供的方法是完全匹配,模糊匹配沒辦法處理,
python 通過import re模塊來實作,呼叫正則運算式的方法,實作模糊匹配

字符匹配(普通字符,元字符):
普通字符:大多數字符和字母都會和自身匹配
元字符:

 

     .  點,占一位,代指所有字符,除了換行符,
    ^  尖角號,只從字串開頭 開始匹配,
    $  dollar符,只從字串結尾 開始匹配,

    *  星號,把前一個(普通字符、一個或者幾個元字符)重復匹配0到無窮次,
    +  加號,把前一個(普通字符、一個或者幾個元字符)重復匹配1到無窮次,
    ?  問號,把前一個(普通字符、一個或者幾個元字符)重復匹配0到1次,
    {}  {3}指定匹配前一個元素重復3次,{1,3}指定匹配前一個元素重復1/2/3次

    []  字符集,[cd]匹配兩者之一,[a-z]匹配26個字母之一,[a*]把元字符變成普通字符
    |   管道,符號兩邊取或
    ()  分組,把正則運算式中需要回傳的值括起來,
    \  反斜杠后邊跟元字符是去除特殊功能的,反斜杠后面跟普通字符可以實作特殊功能:
        \d  匹配任何十進制數;它相當于類[0-9]
        \D  匹配任何非數字字符;它相當于類[^0-9]
        \s  匹配任何空白字符;它相當于類[\t\n\r\f\v]
        \S  匹配任何非空白字符;它相當于類[^\t\n\r\f\v]
        \w  匹配任何字母數字字符;它相當于類[a-zA-Z0-9_]
        \W  匹配任何非字母數字字符;它相當于類[^a-zA-Z0-9_]
        \b  匹配任何一個特殊字符邊界,
元字符
    re.findall() #匹配到 回傳字串組成的串列,沒有結果回傳空串列,
    re.search().group()  #找到第一個匹配值后就回傳,回傳結果是一個Match object,需要通過.group()提取資料,如果沒有結果,回傳None
    re.match().group()  #同search,不過僅在字串開始處進行匹配,
    re.split("[ab]","abcd")   #先按'a'分隔得到""和"bcd",再對""和"bcd"按照'b'分割
    re.sub("\d","abc","alvin5yuan6",1)  #第四位引數,指定替換幾個值
    re.finditer('\d',"acd3d4f5")  #把匹配值放進迭代器
re的方法
import re


g = re.finditer('\d',"acd3d4f5")  # 迭代器
print(next(g).group())
print(next(g).group())

u = re.sub("\d","abc","alvin5yuan6",1)  # alvinabcyuan6
print(u)

x1 = re.findall("i\\b","i like python")  # ['i']  \b 捕捉特殊字符邊界,
print(x1)
x = re.findall("i\\b","i li$e python")  # ['i', 'i']  \b 捕捉特殊字符邊界,
print(x)

z7 = re.findall("[^ab]","a*ba2ba2*b,a2a*")  # ['*', '2', '2', '*', '2', '*']  尖角號,取消特殊功能后,放在[]里頭是取反的意思
print(z7)
z6 = re.findall("a,b","a,ba2ba2,ba2a,")  # ['a,b']  逗號
print(z6)
z5 = re.findall("a[2,]b","a,ba2ba2,ba2a,")  # ['a,b', 'a2b'] 逗號與2 二取一
print(z5)
z4 = re.findall("a[2*]b","a*ba2ba2*ba2a*")  # ['a*b', 'a2b'] 星號與2 二取一,取消星號特殊功能
print(z4)

z3 = re.findall("a[0-9]b","acbadbasdba2b")  # ['a2b']
print(z3)
z2 = re.findall("a[a-z]b","acbadbasdba2b")  # ['acb', 'adb']
print(z2)
z1 = re.findall("a[c,d]b","acbadbasdb")  # ['acb', 'adb']
print(z1)

s5 = re.findall("a{1,}b","aaaaabaababb")   # ['aaaaab', 'aab', 'ab']相當于a+b
print(s5)
s4 = re.findall("a{0,}b","aaaaabaababb")   # ['aaaaab', 'aab', 'ab', 'b'] 相當于a*b
print(s4)
s3 = re.findall("a{1,3}b","aaaaab")   #['aaab'] 默認貪婪匹配
print(s3)
s2 = re.findall("a{1,3}b","aaaaabaababb")   #['aaab', 'aab', 'ab']
print(s2)
s1 = re.findall("a{3}b","aaaaabaababb")   #['aaab']
print(s1)

ret_6 = re.findall("a.*?b","aaaaabaababb")   #['aaaaab', 'aab', 'ab']
print(ret_6)
ret_5 = re.findall("a.*b","aaaaabaababb")   #['aaaaabaababb']
print(ret_5)
ret_4 = re.findall("a*b","aaaaabaababb")   #['aaaaab', 'aab', 'ab', 'b']
print(ret_4)

ret_3 = re.findall("a+b","aaaaabaababb")  # ['aaaaab', 'aab', 'ab']
print(ret_3)

ret_3 = re.findall("如.*哈","如哈")
print(ret_3)

ret_2 = re.findall("a..x$","alexh")  # []  $ dollar符要求只從字串結尾開始匹配,
print(ret_2)
ret_1 = re.findall("^h...0","hjsonhello")  # [] ^尖角號要求只從字串開頭開始匹配,
print(ret_1)
ret = re.findall("w\w{2}l","hello world")
print(ret)   # ['worl']
例子
練習 開發一個簡單的python計算器
1.實作加減乘除及括號優先級決議
2.用戶輸入1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))等類似公式后,必須自己決議里面的(),+
,-,*,/符號和公式(不能呼叫eval()函式實作),然后得出結果,


十一、logging模塊

CRITICAL = 50 #FATAL = CRITICAL
ERROR = 40
WARNING = 30 #WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0 #不設定
日志級別

默認級別為warning,默認列印到終端

最簡單的日志檔案

可在logging.basicConfig()函式中通過具體引數來更改logging模塊默認行為,可用引數有
filename:用指定的檔案名創建FiledHandler(后邊會具體講解handler的概念),這樣日志會被存盤在指定的檔案中,
filemode:檔案打開方式,在指定了filename時使用這個引數,默認值為“a”還可指定為“w”,
format:指定handler使用的日志顯示格式, 
datefmt:指定日期時間格式, 
level:設定rootlogger(后邊會講解具體概念)的日志級別 
stream:用指定的stream創建StreamHandler,可以指定輸出到sys.stderr,sys.stdout或者檔案,默認為sys.stderr,若同時列出了filename和stream兩個引數,則stream引數會被忽略,



#格式
%(name)s:Logger的名字,并非用戶名,詳細查看

%(levelno)s:數字形式的日志級別

%(levelname)s:文本形式的日志級別

%(pathname)s:呼叫日志輸出函式的模塊的完整路徑名,可能沒有

%(filename)s:呼叫日志輸出函式的模塊的檔案名

%(module)s:呼叫日志輸出函式的模塊名

%(funcName)s:呼叫日志輸出函式的函式名

%(lineno)d:呼叫日志輸出函式的陳述句所在的代碼行

%(created)f:當前時間,用UNIX標準的表示時間的浮 點數表示

%(relativeCreated)d:輸出日志資訊時的,自Logger創建以 來的毫秒數

%(asctime)s:字串形式的當前時間,默認格式是 “2003-07-08 16:49:45,896”,逗號后面的是毫秒

%(thread)d:執行緒ID,可能沒有

%(threadName)s:執行緒名,可能沒有

%(process)d:行程ID,可能沒有

%(message)s:用戶輸出的訊息

 
logging.basicConfig()
basicConfig
#========使用
import logging
logging.basicConfig(filename='access.log',
                    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S %p',
                    level=10)

logging.debug('除錯debug')
logging.info('訊息info')
logging.warning('警告warn')
logging.error('錯誤error')
logging.critical('嚴重critical')





#========結果
access.log內容:
2017-07-28 20:32:17 PM - root - DEBUG -test:  除錯debug
2017-07-28 20:32:17 PM - root - INFO -test:  訊息info
2017-07-28 20:32:17 PM - root - WARNING -test:  警告warn
2017-07-28 20:32:17 PM - root - ERROR -test:  錯誤error
2017-07-28 20:32:17 PM - root - CRITICAL -test:  嚴重critical
初級日志檔案
#logger:產生日志的物件

#Filter:過濾日志的物件

#Handler:接收日志然后控制列印到不同的地方,FileHandler用來列印到檔案中,StreamHandler用來列印到終端

#Formatter物件:可以定制不同的日志格式物件,然后系結給不同的Handler物件使用,以此來控制不同的Handler的日志格式


通過handler 給logger 物件 多個輸出方式,fornatter為 logger 指定輸出格式
復雜的日志檔案

 

import logging
from logging import handlers

# 生成logger物件
logger = logging.getLogger('web')
logger.setLevel(logging.DEBUG)

# 生成handler物件
ch = handlers.RotatingFileHandler('test.log',maxBytes=50,backupCount=2)
fh = logging.FileHandler('web.log')

# 把handler物件系結到logger
logger.addHandler(ch)
logger.addHandler(fh)


# 生成formatter物件
ch_formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s')
ch.setLevel(logging.INFO)
fh_formatter = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(levelno)s-%(message)s')
fh.setLevel(logging.WARNING)

# 把formatter物件系結到logger
ch.setFormatter(ch_formatter)
fh.setFormatter(fh_formatter)


logger.debug('debug')
logger.info('info')
logger.warning('warning')
logger.critical('critical')
logger.error('error')
logging 多個handler
 def get_logger():
        logger = logging.getLogger('ftp')  # 創建一個logger物件
        logger.setLevel(logging.INFO)  # 設定日志級別

        # handler
        ch = logging.StreamHandler()  # 創建一個handler物件
        filename = settings.LOGGING_DIR
        fh = logging.FileHandler(filename)  # 創建一個handler物件

        # formatter
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(filename)s - %(message)s')
        # bind formatter to handler
        ch.setFormatter(formatter)
        fh.setFormatter(formatter)

        # add handler to logger
        logger.addHandler(ch)
        logger.addHandler(fh)
        return logger

get_logger().info('記錄一下...')
輸出到檔案和終端的日志

 

需要注意的是filter的順序,

logger的 日志級別是第一級過濾,

然后會給handler,

 

十三、subrocess 模塊

import subprocess   

  def for_shell(self,head_dic):
        """這個就是處理系統命令,拿到執行結果"""
        cmd = head_dic['cmd']
        obj = subprocess.Popen(cmd,shell=True,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
        stdout, stderr = obj.stdout.read().decode('GBK'),obj.stderr.read().decode('GBK')
        res_head_dic = {'res': stderr + stdout}
        return res_head_dic
subprocess

 

 

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/71730.html

標籤:Python

上一篇:Qt 之 Graphics View Framework 簡介

下一篇:Python 函式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more