中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python configparser模塊 與 subprocess 模塊

發布時間:2020-07-02 18:11:30 來源:網絡 閱讀:737 作者:LJ_baby 欄目:編程語言

configparser 模塊

Python中 configparser 模塊用于讀取和編輯配置文件,更多的是用于讀取配置文件。配置文件的格式如下,可以包含多個section(例如:db,email),每個section又可以有多個鍵值對(例如:database=bps);其中 '=' 也可以使用 ':' 取代~

[default]
log_path=/tmp/csv.log

[db]
host=192.168.1.20
database=bps
user=bps
password=123456

[email]
smtp_server=1.2.3.4
smtp_port=587
mailfrom=kitty@163.com
mailfrom_pass=123456

生成配置文件

生成如上示例的配置文件:

import configparser

config = configparser.ConfigParser()
config['default'] = {'log_path': '/tmp/csv.log'}

config['db'] = {'host': '192.168.1.20',
                'database': 'bps',
                'user': 'bps',
                'password': '123456'}

config['email'] = {'smtp_server': '1.2.3.4',
                'smtp_port': '587',
                'usmailfromer': 'kitty@163.com',
                'mailfrom_pass': '123456'}

# 寫入到配置文件,執行 config.ini 配置文件的路徑為當前路徑~
with open(file='config.ini',mode='w') as f:
    config.write(f)

執行后,在當前目錄下,可以看到已生成的 config.ini 文件:
Python configparser模塊 與 subprocess 模塊

文件內容如下:
Python configparser模塊 與 subprocess 模塊

讀取配置文件

更多的時候,我們是手動編輯配置文件,在程序運行時讀取配置信息。

config = configparser.ConfigParser()
print(config.sections())   # []

# 讀取配置文件 config.ini
config.read('config.ini')

# 打印 config.ini 文件中的所有 section,以列表的形式返回
print(config.sections())    # ['default', 'db', 'email']

# 判斷指定的 section 是否存在
print('email' in config)       # True
print('log_path' in config)  # False
# 或
print(config.has_section('email'))        # True
print(config.has_section('log_path'))   # False

# 打印 config.ini 文件中 指定 section 下的所有 option,以列表的形式返回
print(config.options('email'))   # ['smtp_server', 'smtp_port', 'usmailfromer', 'mailfrom_pass']

# 判斷 指引的 option 是否存在
print('log_path' in config['default'])         # True
# 或
print(config.has_option('email', 'abc'))  # False

# 打印 config.ini 文件中 指定 section 下的所有 鍵值對
print(config.items('db'))      # [('host', '192.168.1.20'), ('database', 'bps'), ('user', 'bps'), ('password', '123456')]

# 獲取 config.ini 文件中 指定 section 下的指定 option 的值,以字符串的形式返回
print(config.get('email', 'smtp_server'))    # 1.2.3.4
# 或
print(config['email']['smtp_server'])         # 1.2.3.4

?

遍歷指定 section 下的所有key

for key in config['db']:
    print(key)

結果輸出:
host
database
user
password

編輯配置文件

除了讀寫操作,還可以對已有的配置文件進行編輯。

config = configparser.ConfigParser()

# 讀取配置文件
config.read('config.ini')

# 增加一個section
if not config.has_section('sftp'):
    config.add_section('sftp')

# 刪除一個section
config.remove_section('email')

# 添加一個 option
if not config.has_option('sftp', 'sftp_server'):
    config.set('sftp', 'sftp_server', '4.3.2.1')

# 刪除一個 option
config.remove_option('db', 'database')

# 修改一個 option
if config.has_option('db', 'user'):
    config.set('db', 'user', 'baby')

注意:以上這些操作只發生在內存中,若要使文件改變,還需要寫入到文件中

with open(file='config.ini', mode='w') as f:
    config.write(f)

再次查看文件,文件內容已經發生修改:
Python configparser模塊 與 subprocess 模塊

subprocess 模塊

subprocess 模塊用于執行外部命令。在python中,可以使用標準庫中的 subprocess模塊 來fork一個子進程,然后使用子進程執行外部命令。主程序可以通過 subprocess模塊 提供的一些管理標準流(standard stream) 和 管道(pipe) 的工具來獲取外部命令的執行結果,以及子進程的執行狀態碼~

os.system() 和 os.popen()

os.system() 會打開一個子shell(子進程)來執行系統命令,命令的執行結果會輸出到stdout,也就是直接打印到終端,方法會返回狀態碼,如下所示:

import os

return_code = os.system('ls -l /tmp')
print(return_code)

# 輸出結果:
lrwxr-xr-x@ 1 root  wheel  11 Sep 25 20:16 /tmp -> private/tmp
0

?
os.popen() 的執行會將外部命令的執行結果輸出到管道,方法返回一個連接管道的文件對象。如果外部命令執行成功,則不會返回狀態碼,若執行失敗,錯誤信息會輸出到stdout(即直接打印到終端),并返回一個空字符串。操作該文件對象的方式與普通的讀寫文件操作一致,如下示例:

import os

f = os.popen('cat /Users/James/abc')
print(f.readlines())

# 輸出結果:
['hello\n', 'kitty\n']

?
和 subprocess模塊 一樣,以上兩種方式也可以用來執行外部命令,但是這兩個方法過于簡單,不能完成復雜的操作,例如管理命令的輸入輸出,獲取命令的運行狀態等~,subprocess 模塊可以滿足這些需求,所以如官方建議,使用subprocess模塊來生成新進程并獲取結果是更好的選擇。
?
在 subprocess 模塊中,有很多個函數,這些函數都有各自的方式創建子進程,執行外部命令~

subprocess.run()

run方法 會直接輸出命令的執行結果,并返回 CompletedProcess 對象

code = subprocess.run(["df","-h"])   # 輸出命令的執行結果
print(code)              # CompletedProcess(args=['df', '-h'], returncode=0)

# 獲取命令的狀態碼
print(code.returncode)   # 0
subprocess.call()

call方法 會直接輸出命令的執行結果,并返回 狀態碼

res = subprocess.call(["ls","-l"])   # 輸出命令的執行結果

# 獲取命令的狀態碼
print(res)    # 0
subprocess.check_call()

check_call 方法內部其實調用了call方法,當狀態碼為0時,同call方法一致,若狀態碼不為0,則拋出 CalledProcessError 異常

res = subprocess.check_call(["ls","-l"])
print(res)    # 0
subprocess.check_output()

check_output方法 接收的參數只能是一個沒有參數的外部命令,返回執行的結果,內部實現方式是調用了 run 方法

res = subprocess.check_output("pwd")
print(res)     # 即返回當前路徑
subprocess.getstatusoutput()

getstatusoutput方法 接受字符串形式的命令,返回 一個元組形式的結果,第一個元素是命令執行狀態,第二個為執行結果

res = subprocess.getstatusoutput('ls -l /tmp')
print(res)      # (0, 'lrwxr-xr-x@ 1 root  wheel  11 Sep 25 20:16 /tmp -> private/tmp')

?

若執行錯誤,則同樣會返回錯誤信息

res = subprocess.getstatusoutput('abc')
print(res)

# 結果輸出:
(127, '/bin/sh: abc: command not found')
subprocess.getoutput()

getoutput方法 接受字符串形式的命令,返回執行結果,不會返回狀態碼

res = subprocess.getoutput('ls -l /tmp/')
print(res)

# 結果輸出:
total 8
......
......
-rw-r--r--  1 baby  wheel  446 Dec 21 14:14 csv.log
drwxr-xr-x  2 root  wheel   64 Dec 19 15:03 powerlog

以上這些方法都是直接或者間接的調用了subprocess.Popen 方法,建議在使用過程中直接使用 subprocess.Popen 方法~

subprocess.Popen()

res = subprocess.Popen("cat /etc/passwd", shell=True)   

# 結果輸出(即 /etc/passwd 文件的內容):
##
# User Database
...
##
nobody:*:-2:-2:Unprivileged User:/var/empty:/usr/bin/false
root:*:0:0:System Administrator:/var/root:/bin/sh
daemon:*:1:1:System Services:/var/root:/usr/bin/false
......
......

subprocess.Popen 方法創建的子進程執行外部命令后,會將返回結果 輸出到 stdin/stdout/stderr 中,這樣會直接打印到終端。也可以將返回信息寫入到一個緩存區(或稱之為管道),主進程從緩存區中讀取子進程的返回信息~

res = subprocess.Popen("cat /tmp/csv.log", shell=True, stdout=subprocess.PIPE)
print(res.stdout.read())

# 結果輸出:
b'abc\n'

?
將正確輸出和錯誤輸出都寫入到緩存區中

res = subprocess.Popen("lm /tmp", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(res.stdout.read())   # b''
print(res.stderr.read())     # b'/bin/sh: lm: command not found\n'

?
也可以利用 subprocess.PIPE 將多個子進程的輸入和輸出連接在一起,構成管道(pipe),即 s1 的輸出結果作為 s2 的輸入信息:

s1 = subprocess.Popen(["cat", "/etc/passwd"], stdout=subprocess.PIPE)
s2 = subprocess.Popen(["grep", "0:0"], stdin=s1.stdout, stdout=subprocess.PIPE)
out = s2.communicate()
print(out)

# 輸出結果:
(b'root:*:0:0:System Administrator:/var/root:/bin/sh\n', None)

?
其中的 communicate() 方法下面會介紹~

注意::運行 subprocess.Popen() 后,主進程不會等待子進程執行完畢,而是會繼續往下執行~

poll()

poll 方法用于判斷子進程是否執行完畢,若沒有執行完畢返回 None,若是執行完成,返回 執行狀態碼~

res = subprocess.Popen("sleep 5;echo 'end'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(res.poll())    # None
time.sleep(6)
print(res.poll())    # 0
wait()

wait方法 會等待命令執行完成(即主進程阻塞),并且返回 執行狀態碼~

res = subprocess.Popen("sleep 5;echo 'end'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

# 等待子進程執行完畢,并返回狀態碼
print(res.wait())      # 0
terminate()

terminate方法能終止正在運行中的子進程

res = subprocess.Popen("sleep 5;echo 'end'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
res.terminate()

# 子進程被終止后,沒有返回信息
print(res.stdout.read())    # b''
獲取子進程的pid

pid 為 subprocess.Popen 對象的一個變量,保存了子進程的進程號

res = subprocess.Popen("sleep 5;echo 'end'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(res.pid)       # 36777
communicate()

執行 communicate 方法后,主進程會等待(主進程阻塞)子進程運行完畢,并從 subprocess.PIPE 中會獲取子進程的返回信息,返回一個tuple(標準輸出和錯誤輸出)

res = subprocess.Popen("sleep 5;echo 'end'", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(res.communicate())     # 主進程執行到這一步,不再繼續往下執行,會等待子進程運行完畢~

# 錯誤輸出
res = subprocess.Popen("lm -l", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(res.communicate())

# 結果輸出:
(b'end\n', b'')
(b'', b'/bin/sh: lm: command not found\n')

.................^_^

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

济源市| 响水县| 汕尾市| 韩城市| 凌源市| 安阳市| 吉林省| 遂宁市| 武夷山市| 岫岩| 东乡族自治县| 阜南县| 历史| 揭西县| 会宁县| 西贡区| 博兴县| 赫章县| 子洲县| 海城市| 灯塔市| 讷河市| 灵丘县| 南川市| 沁源县| 城步| 平塘县| 阿拉尔市| 鲜城| 台南县| 乌恰县| 平顶山市| 乐安县| 鸡泽县| 石河子市| 中山市| 凌海市| 邛崃市| 寿阳县| 永丰县| 宁城县|