天天看點

python學習之路-day7

一、常用子產品

    shutil    

    xml    

    configparser  

    hashlib  

    subprocess

    1、shutil子產品

    用途:進階的檔案、檔案夾、壓縮包處理子產品

    shutil.copyfileobj(fsrc,fdst[,length])

    将檔案内容拷貝到另一個檔案中

1 import shutil
2 shutil.copyfileobj(open('old.xml','r'),open('new.xml','w'))      

    shutil.copyfile(src,dst)

    拷貝檔案

til.copyfile('haha.log','xixi.log')   #目标檔案無需存在      

    shutil.copymode(src,dst)

    僅拷貝權限。内容、組、使用者均不變

shutil.copymode('haha.log','xixi.log')   #目标檔案必須存在      

    shutil.copystat(src,dst)

    僅拷貝狀态的資訊,包括:mode bits,atime,mtime,flags

shutil.copystat('haha.log','xixi.log')     #目标檔案必須存在      

    shutil.copy(src,dst)

    拷貝檔案和權限

shutil.copy('haha.log','xixi.log')      

    shutil.copy2(src,dst)

    拷貝檔案和狀态資訊

shutil.copy2('haha.log','xixi.log')      

    shutil.ignore_patterns(*patterns)

    shutil.copytree(src,dst,symlinks=False,ignore=None)

    遞歸的去拷貝檔案夾

shutil.copytree('old_dir','new_dir',ignore=shutil.ignore_patterns('*.pyc','tmp*'))       #目标目錄不能存在,注意對new_dir目錄父目錄要有可寫權限,ignore的意思是排除      
shutil.copytree('f1','f2',symlinks=True,ignore=shutil.ignore_patterns('*.pyc','tmp*'))

#通常對的拷貝都把軟連結拷貝成硬連結,即對待軟連結來說,建立新的檔案      

拷貝軟連結

    shutil.rmtree(path[,ignore_errors[,onerror]])

    遞歸的去删除檔案

shutil.rmtree('old_dir')      

    shutil.move(src,dst)

    遞歸的去移動檔案,它類似mv指令,其實就是重命名

shutil.move('old_file','new_file')      

    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下的檔案打包放置目前程式目錄
ret = shutil.make_archive('data_bak','gztar',root_dir='/data')

#将 /data下的檔案打包放置 /tmp/目錄
ret = shutil.make_archive('/tmp/data_bak','gztar',root_dir='/data')      
import zipfile

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

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

zipfile壓縮解壓縮

import tarfile

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

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

tarfile壓縮解壓縮

    2、xml子產品

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

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

<data>
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year>2008</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    <egon age="18">hello</egon></country>
    <country name="Singapore">
        <rank updated="yes">5</rank>
        <year>2011</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    <egon age="18">hello</egon></country>
    <country name="Panama">
        <year>2011</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    <egon age="18">hello</egon></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('a.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)

#增加node
for country in root.iter('country'):
    e = ET.Element('xiaoyu')
    e.text = 'hello'
    e.attrib = {'age':'18'}
    country.append(e)
tree.write('a.xml')
#删除node
for country in root.iter('country'):
    print(country.tag)
    rank = country.find('rank')
    if int(rank.text) > 10:
        country.remove(rank)
tree.write('a.xml')
#修改node
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('a.xml')      

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) #列印生成的格式      

建立xml檔案

3、configparser子產品

      
# 注釋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')


#删除整個标題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'))      

    4、hashlib子產品

hash:一種算法 ,3.x裡代替了md5子產品和sha子產品,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

三個特點:

1.内容相同則hash運算結果相同,内容稍微改變則hash值則變

2.不可逆推

3.相同算法:無論校驗多長的資料,得到的哈希值長度固定。

import hashlib

m = hashlib.md5()
m.update('hello'.encode('utf-8'))
print(m.hexdigest())    #5d41402abc4b2a76b9719d911017c592

m.update('haha'.encode('utf-8'))
print(m.hexdigest())    #ab540ca02784f1e2f0fb8e1d2d1d92a9

m2 = hashlib.md5()
m2.update('hellohaha'.encode('utf-8'))
print(m2.hexdigest())   #ab540ca02784f1e2f0fb8e1d2d1d92a9

'''
注意:把一段很長的資料update多次,與一次update這段長資料,得到的結果一樣
但是update多次為校驗大檔案提供了可能。
'''      
以上加密算法雖然依然非常厲害,但時候存在缺陷,即:通過撞庫可以反解。是以,有必要對加密算法中添加自定義key再來做加密。

      
import hashlib
 
# ######## 256 ########
 
hash = hashlib.sha256('898oaFs09f'.encode('utf8'))
hash.update('alvin'.encode('utf8'))
print (hash.hexdigest())#e79e68f070cdedcfe63eaf1a2e92c83b4cfb1b5c6bc452d214c1b7e77cdfd1c7      
import hashlib
passwds=[
    'alex3714',
    'alex1313',
    'alex94139413',
    'alex123456',
    '123456alex',
    'a123lex',
    ]
def make_passwd_dic(passwds):
    dic={}
    for passwd in passwds:
        m=hashlib.md5()
        m.update(passwd.encode('utf-8'))
        dic[passwd]=m.hexdigest()
    return dic

def break_code(cryptograph,passwd_dic):
    for k,v in passwd_dic.items():
        if v == cryptograph:
            print('密碼是===>\033[46m%s\033[0m' %k)

cryptograph='aee949757a2e698417463d47acac93df'
break_code(cryptograph,make_passwd_dic(passwds))      

模拟撞庫破解密碼

python 還有一個 hmac 子產品,它内部對我們建立 key 和 内容 進行進一步的處理然後再加密:

import hmac
2 h = hmac.new('alvin'.encode('utf8'))    #加鹽
3 h.update('hello'.encode('utf8'))
4 print (h.hexdigest())#320df9832eab4c038b6c1d7ed73a5940      
#要想保證hmac最終結果一緻,必須保證:
#1:hmac.new括号内指定的初始key一樣
#2:無論update多少次,校驗的内容累加到一起是一樣的内容

import hmac

h1=hmac.new(b'egon')
h1.update(b'hello')
h1.update(b'world')
print(h1.hexdigest())

h2=hmac.new(b'egon')
h2.update(b'helloworld')
print(h2.hexdigest())

h3=hmac.new(b'egonhelloworld')
print(h3.hexdigest())

'''
f1bf38d054691688f89dcd34ac3c27f2
f1bf38d054691688f89dcd34ac3c27f2
bcca84edd9eeb86f30539922b28f3981
'''      

注意!

5、subprocess子產品

      
import  subprocess

'''
sh-3.2# ls /Users/egon/Desktop |grep txt$
mysql.txt
tt.txt
事物.txt
'''

res1=subprocess.Popen('ls /Users/jieli/Desktop',shell=True,stdout=subprocess.PIPE)
res=subprocess.Popen('grep txt$',shell=True,stdin=res1.stdout,
                 stdout=subprocess.PIPE)

print(res.stdout.read().decode('utf-8'))


#等同于上面,但是上面的優勢在于,一個資料流可以和另外一個資料流互動,可以通過爬蟲得到結果然後交給grep
res1=subprocess.Popen('ls /Users/jieli/Desktop |grep txt$',shell=True,stdout=subprocess.PIPE)
print(res1.stdout.read().decode('utf-8'))


#windows下:
# dir | findstr 'test*'
# dir | findstr 'txt$'
import subprocess
res1=subprocess.Popen(r'dir C:\Users\Administrator\PycharmProjects\test\函數備課',shell=True,stdout=subprocess.PIPE)
res=subprocess.Popen('findstr test*',shell=True,stdin=res1.stdout,
                 stdout=subprocess.PIPE)

print(res.stdout.read().decode('gbk')) #subprocess使用目前系統預設編碼,得到結果為bytes類型,在windows下需要用gbk解碼      

 二、面向對象

  1、面向對象與面向過程的差別:

    面向過程:核心是過程二字,過程指的是問題的解決步驟,即先幹什麼再幹什麼,基于面向過程去設計程式就好比在設計一條流水線,是一種機械式的思維方式

    優點:複雜的問題流程化,進而簡單化

    缺點:可擴充性差

    應用:腳本程式,比如linux系統管理腳本,著名案例:linux核心、httpd、git

    面向對象 :核心是對象二字,對象就是特征與技能的結合體,如果把設計程式比喻成創造一個世界,那你就是這個世界的上帝,與面向過程對機械流水的模拟形成鮮明的對比,面向對象更加注重的對現實時間的模拟

    優點:可擴充性

    缺點:

    類即種類,類别,對象是特種和技能的結合體,那麼類就是一系列對象相似的特征與技能的結合體

    在現實世界中:先有一個個具體存在的對象

    在程式中:一定是先定義類,後調用類來産生對象

1 class OldboyStudent:
 2     school = 'oldboy'    #類的資料屬性
 3     def learn(self):      #類的函數屬性
 4         print('is learning')
 5 
 6     def eat(self):
 7         print('is eating')
 8 #類體的代碼在類定義階段就會執行,理所當然會産生類的名稱空間,用_dict_屬性檢視
 9 print(OldboyStudent.__dict__)
10 print(OldboyStudent.__dict__['school'])
11 print(OldboyStudent.__dict__['learn'])
12 
13 #類的屬性操作
14 print(OldboyStudent.school)
15 print(OldboyStudent.learn)
16 OldboyStudent.x = 1111111111111
17 OldboyStudent.school = 'Oldboy'
18 del OldboyStudent.school
19 print(OldboyStudent.__dict__)
20 OldboyStudent.__dict__['x'] = 111111111   #類的屬性無法用字典方式修改      

類的定義和操作

    産生程式中的對象:類名加括号,調用類,産生一個該類的實際存在的對象,該調用過程稱為執行個體化,産生的結果又可以稱為執行個體化對象

class OldboyStudent:
    school = 'oldboy' 
    count = 0
    def __init__(self,age,name,sex):  #在執行個體化時,産生對象之後執行
        self.age = age
        self.name = name
        self.sex = sex

    def learn(self):  
        print('%s is learning' %self.name)

obj1 = OldboyStudent(20,'小雨','male')
#分兩步:
#第一步:産生一個空對象obj1
#第二步:OldboyStudent.__init__(obj1,20,'小雨','male')

print(obj1.__dict__)
OldboyStudent.learn(obj1)
obj1.learn()  #等同于OldboyStudent.learn(obj1)

obj1.name = '哈哈'               #對象可以通過__dict__修改私有屬性
obj1.__dict__.pop('name')      

    2、繼承:

        指的是類與類之間的關系,是一種什麼是什麼的關系,功能之一就是用來解決代碼重用的問題。繼承是一種建立新類的方式,在python中,建立的類可以繼承一個或多個父類,父類又可稱為基類或超類,建立的類稱為派生類或子類

    繼承分為單繼承和多繼承:

class ParentClass1:
    pass
class ParentClass2:
    pass
class SubClass1(ParentClass1):
    pass
class SubClass2(ParentClass1,ParentClass2):
    pass

print(SubClass1.__bases__)      #會以元組形式展示父類
print(SubClass2.__bases__)            

    在子類派生出的新的方法内重用父類的功能方式:指名道姓法

    OldboyPeople.__init__ 這種調用方式本身與繼承是沒有關系的

class OldboyPeople:
    school = 'oldboy'
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print('is eating')

class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex,course):
        super().__init__(name,age,sex)
        self.course = course

    def tell_info(self):
        print('%s 選擇了 %s課程' %(self.name,self.course))

yu_obj = OldboyStudent('xiaoyu',18,'male','Python')
yu_obj.tell_info()      

super方法

class OldboyPeople:
    school = 'oldboy'
    def __init__(self,name,age,sex):
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print('is eating')

class OldboyStudent(OldboyPeople):
    def __init__(self,name,age,sex):
        OldboyPeople.__init__(self,name,age,sex)

    def learn(self):
        print('%s is learning' %self.name)

class OldboyTeacher(OldboyPeople):
    def  __init__(self,name,age,sex,salary,title):
        OldboyPeople.__init__(self,name,age,sex)
        self.salary = salary
        self.title = title
        self.course = []
    def teach(self):
        print('%s is teaching' %self.name)

class Course:
    def __init__(self,course_name,course_period,course_price):
        self.course_name = course_name
        self.course_period = course_period
        self.course_price = course_price

    def tell_info(self):
        print('<課程名:%s 周期:%s 價格:%s>' %(self.course_name,self.course_period,self.course_price))

python = Course('Python','6mons',3000)
linux = Course('Linux','3mons',2000)
bigdata = Course('Bigdata','1mons',1000)
xy_obj = OldboyStudent('xiaoyu',18,'male')
egon_obj = OldboyTeacher('egon',28,'male',3.1,'沙河一霸')
egon_obj.course.append(linux)
egon_obj.course.append(python)

for i in  egon_obj.course:
    i.tell_info()      

組合

轉載于:https://www.cnblogs.com/xiaoyu866/p/7354539.html