Python從基礎到精通day4

系統管理模塊 、 語法風格及佈局 、 字符串詳解 、

- python官方文檔:https://docs.python.org/zh-cn/3/library/index.html

shutil

  • 實現文件複製、剪切、刪除等功能
>>> import shutil
>>> f1 = open('/etc/issue', 'rb')
>>> f2 = open('/tmp/issue', 'wb')
>>> shutil.copyfileobj(f1, f2)
>>> f1.close()
>>> f2.close()

# 拷貝文件
>>> shutil.copy('/etc/issue', '/tmp/issue2')
# 拷貝目錄
>>> shutil.copytree('/etc/security', '/tmp/security')
# 移動
>>> shutil.move('/tmp/security', '/var/tmp/')
# 改變屬主屬組
>>> shutil.chown('/tmp/issue', user='student', group='student')
# 刪除目錄
>>> shutil.rmtree('/var/tmp/security')

subprocess

  • subprocess模塊用於執行系統命令
# 使用時,只需要改變字符串中的命令即可,其餘部分都是固定寫法。shell=True表示在shell環境下執行命令;stdout是將標準輸出內容放到stdout中,stderr是將標準錯誤內容放到stderr變量中
>>> result = subprocess.run('id zhangsan', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> result
CompletedProcess(args='id zhangsan', returncode=1, stdout=b'', stderr=b'id: zhangsan: no such user\n')
# 在python中一切皆對象,不同對象有不同的屬性。result顯示的內容,括號中的每個部分都是它的屬性
# 在python中屬性、方法都使用句點表示
>>> result.args   # 執行的命令
>>> result.returncode   # 即$?
>>> result.stdout   # 標準輸出,bytes類型
>>> result.stderr   # 標準錯誤
>>> result.stdout.decode()  # 將bytes類型轉爲str類型

案例1 shutil模塊和subprocess模塊的使用

import subprocess
import  shutil
shutil.copy('/etc/passwd','/root/passwd2')
shutil.move('/root/passwd2','/tmp')
result  = subprocess.run('ls /tmp/passwd2',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
print(result)
if result.returncode == 0:
        print('上條命令執行成功')
else:
        print('上條命令執行失敗')

測試運行:
[root@python day4]# python3 lianxi.py
CompletedProcess(args=‘ls /tmp/passwd2’, returncode=0, stdout=b’/tmp/passwd2\n’, stderr=b’’)
上條命令執行成功

語法查漏補缺

# 鏈式多重賦值
>>> a = b = 10
>>> id(a)   # 查看變量在內存中的地址
9360736
>>> id(b)
9360736
# 示意圖如下:
10
a
b
# 鏈式多重賦值,要注意可變對象
>>> l1 = l2 = [1, 2]
>>> id(l1)
139823060958024
>>> id(l2)
139823060958024
>>> l1
[1, 2]
>>> l2
[1, 2]
>>> l2.append(10)
>>> l2
[1, 2, 10]
>>> l1
[1, 2, 10]

# 多元賦值
>>> a, b = 'xy'
>>> a
'x'
>>> b
'y'
>>> c, d = [10, 20]
>>> c
10
>>> d
20
>>> e, f = ('tom', 'jerry')
>>> e
'tom'
>>> f
'jerry'
>>> g, h = 100, 200
>>> g
100
>>> h
200

# 其他語言交換兩個變量的值
>>> a, b = 10, 20
>>> a
10
>>> b
20
>>> t = a
>>> a = b
>>> b = t
>>> a
20
>>> b
10
# python交換兩個變量的值
>>> a, b = b, a
>>> a
10
>>> b
20
  • 關鍵字:爲了完成語法結構,python有一些系統保留字叫關鍵字。關鍵字不允許被覆蓋
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
  • 內建:python實現的一些內建結構,如內建函數。它們可以被覆蓋,但是不推薦。https://docs.python.org/zh-cn/3/library/functions.html
>>> len('abc')
3
>>> len = 10
>>> len('abc')  # 報錯

模塊文件佈局

#!/usr/local/bin/python3    # 解釋器
"""文檔字符串

對該模塊進行一些說明,用於在help(模塊)顯示幫助信息
"""

import time   			    # 模塊導入
import string

# 全局變量定義
all_chs = string.ascii_letters + string.digits

class MyClass:
    類的聲明

def func1():
    函數聲明

if __name__ == '__main__':
    程序主體代碼

編程思路

  1. 發呆。思考程序的運行方式。交互?非交互?
[root@localhost day04]# python3 mk_file.py 
文件名: /etc
文件已存在,請重試。
文件名: /etc/hosts
文件已存在,請重試。
文件名: /tmp/abc.txt
請輸入文件內容,在單獨的一行輸入end結束。
(end to quit)> Hello World!
(end to quit)> 你好!
(end to quit)> the end
(end to quit)> end
[root@localhost day04]# ls /tmp/abc.txt
/tmp/abc.txt
[root@localhost day04]# cat /tmp/abc.txt
Hello World!
你好!
the end
  1. 思考程序有哪些功能,將這些功能聲明爲功能函數。
def get_fname():
    "用於獲取文件名"

def get_content():
    "用於獲取內容"

def wfile(fname, content):
    "將內容content寫入文件fname"
  1. 編寫程的主體代碼,按照一定之規,依次調用函數
def get_fname():
    "用於獲取文件名"

def get_content():
    "用於獲取內容"

def wfile(fname, content):
    "將內容content寫入文件fname"

if __name__ == '__main__':
    fname = get_fname()
    content = get_content()
    wfile(fname, content)
  1. 完成各個函數

案例2

編寫mktxtfile.py腳本,實現以下目標:
編寫一個程序,要求用戶輸入文件名
如果文件已存在,要求用戶重新輸入
提示用戶輸入數據,每行數據先寫到列表中
將列表數據寫入到用戶輸入的文件名中

import os
def get_fname():
    while 1:
        filename = input('請輸入文件名:')
        if not os.path.exists(filename):
            break
        print('%s 文件以存在。'% filename)
    return filename


def get_contect():
    contect = []
    print('請輸入內容;end表示退出:')
    while 1:
        neirong = input('(>:)')
        if neirong == 'end':
            break
        contect.append(neirong)
    return  contect

def wfile(fname,contect):
    with open(fname,'w') as fobj:
        fobj.writelines(contect)

if __name__ == '__main__':
    fname = get_fname()
    contect = get_contect()
    contect = ['%s\n' % line for line in contect]
    wfile(fname,contect)

腳本運行:
[root@python day4]# python3 lianxi.py
請輸入文件名:wenhao.txt
請輸入內容;end表示退出:
(>:)今天週三
(>:)明天週四
(>:)後天週五
(>:)end
[root@python day4]# cat wenhao.txt
今天週三
明天週四
後天週五

序列對象

# list將對象轉成列表
>>> l1 = list(range(10))
>>> l1
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# tuple將對象轉成元組
>>> tuple('abc')
('a', 'b', 'c')
>>> tuple(l1)
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
# str將對象轉成字符串
>>> str(10)
'10'

# reversed()函數可以將序列對象翻轉,返回翻轉後的對象,原始數據不變
>>> from random import randint
>>> nums = [randint(1, 100) for i in range(10)]
>>> nums
[56, 35, 53, 2, 55, 23, 14, 49, 10, 6]
>>> reversed(nums)
<list_reverseiterator object at 0x7fef73666128>
>>> list(reversed(nums))
[6, 10, 49, 14, 23, 55, 2, 53, 35, 56]
>>> for i in reversed(nums):
...     print(i)

# sorted()函數用於排序,返回排序後的列表,原始數據不變
>>> sorted(nums)
[2, 6, 10, 14, 23, 35, 49, 53, 55, 56]

# enumerate()函數返回由序列對象的下標和值構成的元組對象
>>> list(enumerate(nums))
[(0, 56), (1, 35), (2, 53), (3, 2), (4, 55), (5, 23), (6, 14), (7, 49), (8, 10), (9, 6)]

>>> for data in enumerate(nums):
...   print(data)

>>> for i, n in enumerate(nums):
...   print(i, n)

字符串

  • 屬於標量、不可變、順序類型
  • 比較大小時,按順序比較
  • 字符串格式化
# 基礎格式:用元組中的內容替換字符串中的佔位符。如果元組中的內容只有一項,()可以省略
"" % ()

# %s是把相應內容轉成str
>>> '%s is %s years old' % ('tom', 20)
'tom is 20 years old'

# %d表示10進制整數
>>> '%s is %d years old' % ('tom', 20)
'tom is 20 years old'
>>> '%s is %d years old' % ('tom', 20.5)
'tom is 20 years old'

# %f表示浮點數
>>> '%s is %f years old' % ('tom', 20.5)
'tom is 20.500000 years old'
# %.1f指的是小數位1位
>>> '%s is %.1f years old' % ('tom', 20.5)
'tom is 20.5 years old'
# %5.2f是總寬度5個字符,小數位2位,不夠寬度補空格
>>> '%5.2f' % (5 / 3)
' 1.67'

>>> '%s%s' % ('name', 'age')
'nameage'
>>> '%s%s' % ('tom', 20)
'tom20'
# %8s表示總寬度爲8,不夠在左側補空格
>>> '%8s%5s' % ('name', 'age')
'    name  age'
>>> '%8s%5s' % ('tom', 20)
'     tom   20'
# %-8s是左對齊
>>> '%-8s%-5s' % ('name', 'age')
'name    age  '
>>> '%-8s%-5s' % ('tom', 20)
'tom     20   '

# 以下不常用
# %#o表示8進制
>>> '%#o' % (10)
'0o12'
# %#x表示16進制
>>> '%#x' % (10)
'0xa'
# %e表示科學計數法
>>> '%e' % 10000
'1.000000e+04'
# 字符串也可以使用format方法
>>> '{} is {} years old'.format('bob', 20)
'bob is 20 years old'
>>> '{1} is {0} years old'.format(20, 'bob')
'bob is 20 years old'
  • 原始字符串
>>> win_path = 'c:\temp\newdir'
print會將\t轉成tab,\n轉成回車
>>> print(win_path)
c:      emp
ewdir
  • 真實字符串
**真實字符串**
字符串前加r,表示字符串中的每項內容都是它字面含義
>>> wpath = r'c:\temp\newdir'
>>> print(wpath)
c:\temp\newdir
>>> wpath
'c:\\temp\\newdir'

案例2:編寫一個創建用戶並將用戶信息存到文件裏的腳本

#!/usr/bin/env python3
import sys  #導入位置模塊
import subprocess #導入系統命令模塊
from random import choice  
from string import ascii_letters,digits
all_str = ascii_letters + digits
def get_pass():
    result =''  #定義一個空的變量,python中變量需要優先定義
    for i in range(8):
        zifu = choice(all_str)
        result += zifu  #result = reslt + zifu
    return result  #將最後結果返回

def add_user(username,password,fname):
    result = subprocess.run('id %s  &> /dev/null' % username,shell=True)  
    #重定向到黑洞,可以不用寫stdout和stderr;他們表示正確輸出和錯誤輸出
    if result.returncode == 0:
        print('%s' % username ,'用戶已存在')
        return  #相當於break,退出循環的作用
    subprocess.run('useradd %s' % username,shell=True,
                   stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    subprocess.run('echo %s | passwd --stdin %s ' % (password,username),shell=True)
    #這裏沒寫stdout和stderr;正確或者錯誤輸出就會顯示到屏幕上。
    
    #定義變量,記錄用戶輸入的信息。
    info = """用戶信息  #定義變量,記錄用戶輸入的信息。
用戶名: %s
密碼: %s
""" % (username,password)
    with open(fname,'a') as fobj:  #用a的方式打開文件,文件內容不會被清除,a表示append追加
        fobj.write(info)


if __name__ == '__main__':
    username = sys.argv[1]  #相當於$1
    fname = sys.argv[2]
    password = get_pass()
    add_user(username, password, fname) #調用函數
    #看次腳本時,從if——name往下看,最後調用add_user模塊,並執行裏面的代碼

測試運行:
[root@python day4]# python3 lianxi.py tom /tmp/tom.txt
更改用戶 tom 的密碼 。
passwd:所有的身份驗證令牌已經成功更新。
[root@python day4]# cat /tmp/kenji.txt
用戶信息
用戶名: tom
密碼: v9qmUTe8

[root@python day4]# python3 lianxi.py root /tmp/tom.txt
root 用戶已存在
#用戶已經存在;
則表示上條命令沒有執行成功
result.returncode 不等於零
則匹配到文中的代碼,執行到return時就會退出循環。

字符串方法

  • https://docs.python.org/zh-cn/3/library/stdtypes.html#text-sequence-type-str
>>> hi = '  \thello world.\n'
>>> hi.strip()   # 去除兩端空白字符
'hello world.'
>>> hi.lstrip()  # 去除左側空白字符
'hello world.\n'
>>> hi.rstrip()  # 去除右側空白字符
'  \thello world.'
>>> 'hello world'.center(50)  # 居中
'                   hello world                    '
>>> 'hello world'.center(50, '*')  # 使用*填充
'*******************hello world********************'
>>> 'hello world'.ljust(50, '#')   # 左對齊
'hello world#######################################'
>>> 'hello world'.rjust(50, '#')   # 右對齊
'#######################################hello world'
>>> 'hello world'.upper()  # 轉大寫
'HELLO WORLD'
>>> 'HELLO WORLD'.lower()  # 轉小寫
'hello world'
>>> 'ni hao'.replace('ni', 'ta')  # 字符串替換
'ta hao'
>>> 'python-is-cool'.split('-')   # 切割字符串
['python', 'is', 'cool']
>>> 'python'.islower()   # 字母都是小寫的嗎?
True
>>> 'python'.isupper()   # 字母都是大寫的嗎?
False
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章