day6 (經常使用模塊和麪向對象基礎)

1、經常使用模塊html

一、random 模塊python

import random

print(random.random()) # 大於0小於1之間的小數
#0.9721739019776539

print(random.randint(1,3)) #大於等於1小於等於3的整數
#3

print(random.randrange(1,3)) #大於等於1小於3的整數
#2

print(random.choice([1,'alex','xglv'])) #1或alex或sb
#1

print(random.sample([1,'alex','xglv'],2)) #列表中任意2個的組合
#['xglv', 'alex']

print(random.uniform(1,4)) #大於1小於4之間的小數
#2.518598386302101

l=[1,3,4,2,5]
random.shuffle(l) #從新爲列表排序 (洗牌)
print(l)
#[4, 2, 3, 1, 5]

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

print(make_code(7))
#HX989L8

 

二、os模塊mysql

  方法linux

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下爲"\r\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[, ...]])  將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path)  返回path所指向的文件或者目錄的最後存取時間
os.path.getmtime(path)  返回path所指向的文件或者目錄的最後修改時間
os.path.getsize(path) 返回path的大小

  實踐算法

import os

print(os.stat(r"/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6/01 經常使用模塊/a.xml"))#獲取文件的信息,可接方法查看具體信息
#os.stat_result(st_mode=33279, st_ino=32539163, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=826, st_atime=1515922529, st_mtime=1515819080, st_ctime=1515840538)
print(os.stat(r'/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6/01 經常使用模塊/a.xml').st_size)
#826
print(os.path.getsize(r'/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6/01 經常使用模塊/a.xml')) #獲取文件的大小
#826

res=os.system('pwd') #執行系統命令 放回結果爲執行是否成功值 0成功
#/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6/01 經常使用模塊
print('====>',res)

print(os.path.split(r'F:/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6/01 經常使用模塊/a.xml'))
#('F:/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6/01 經常使用模塊', 'a.xml')

print(os.path.dirname(r'/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6/01 經常使用模塊/a.xml')) #獲取文件的目錄名
#/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6/01 經常使用模塊

print(os.path.basename(r'/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6/01 經常使用模塊/a.xml')) #獲取文件名
#a.xml

print(os.path.isabs(r'/Users/lvxingguo/PycharmProjects/oldboy/day6')) #路徑是否存在
#True

print(os.path.isabs(r'/Users/lvxingguo/PycharmProjects/oldboy/day6')) #路徑是不是一個絕對路徑 (不判斷文件是否存在)
#True

print(os.path.join('/Users/lvxingguo/PycharmProjects/oldboy/',"day6","lxg.txt"))
#/Users/lvxingguo/PycharmProjects/oldboy/day6/lxg.txt

# print(os.path.join('D:\\','dir1','dir2','a.txt'))

# print(os.path.normcase('c:/windows\\SYstem32\\..'))
#在win下規範路徑 不處理..

# print(os.path.normpath('c://windows\\System32\\../Temp/')) #C:\windows\temp
#在Win下規範目錄和解析.. 切到最終的路徑 linux會直接返回



print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
#/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6

BASE_DIR=os.path.normpath(os.path.join(os.path.abspath(__file__), 
    '..',
    '..'
)) #用join來拼接路徑而後返回執行返回最終路徑
print(BASE_DIR)
#/Users/lvxingguo/PycharmProjects/oldboy/day6/代碼/day6

 

三、sys模塊sql

  方法shell

1 sys.argv           命令行參數List,第一個元素是程序自己路徑
2 sys.exit(n)        退出程序,正常退出時exit(0)
3 sys.version        獲取Python解釋程序的版本信息
4 sys.maxint         最大的Int值
5 sys.path           返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
6 sys.platform       返回操做系統平臺名稱

  實踐編程

import sys
# sys.argv
# sys.exit(0)
# sys.path

print('[%-50s]' %('#'*1)) #-50 左對齊 不夠用空格補齊
#[#                                                 ]
print('[%-50s]' %('#'*2))
#[##                                                ]
print('[%-50s]' %('#'*3))
#[####                                               ]
print('[%-50s]' %('#'*4))
#[#####                                              ]
print('[%-50s]' %('#'*5))
#[######                                             ]

print("[%s]" %("#"*10).ljust(50))
#[##########                                        ]


print('[%%-%ds]' %50) #%% 轉譯% 來打印%
#'[%-50s]'
print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10)
#[##########                                        ]

# print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10)
# print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10)
# print(('[%%-%ds]' %50) %('#'*10)) #'[%-50s]' %('#'*10)

print('%d%%' %30)
#30%

import time

def progress(percent,width=50):  #利用print
    if percent >= 1:
        percent=1
    show_str = ('[%%-%ds]' % width) % ('#' * int(width*percent))
    print('\r%s %d%%' %(show_str,int(100*percent)),end='')

def progress_ljust(percent,width=110): #利用str的ljust方法
    if percent >=1:
        percent = 1
    print("\r[%s] %d%%"%(("="*int(width*percent)+">>").ljust(width),percent*100),end="")


recv_size=0
total_size=102411
while recv_size < total_size:
    time.sleep(0.1)
    recv_size+=1024
    #progress(recv_size/total_size)
    progress_ljust(recv_size/total_size)

 

四、shutil模塊json

http://www.cnblogs.com/linhaifeng/articles/6384466.html#_label5windows

 

五、json和pickle

以前咱們學習過用eval內置方法能夠將一個字符串轉成python對象,不過,eval方法是有侷限性的,對於普通的數據類型,json.loads和eval都能用,但遇到特殊類型的時候,eval就無論用了,因此eval的重點仍是一般用來執行一個字符串表達式,並返回表達式的值。

1 import json
2 x="[null,true,false,1]"
3 print(eval(x)) #報錯,沒法解析null類型,而json就能夠
4 print(json.loads(x)) 

什麼是序列化?

咱們把對象(變量)從內存中變成可存儲或傳輸的過程稱之爲序列化,在Python中叫pickling,在其餘語言中也被稱之爲serialization,marshalling,flattening等等,都是一個意思。

爲何要序列化?

1:持久保存狀態

需知一個軟件/程序的執行就在處理一系列狀態的變化,在編程語言中,'狀態'會以各類各樣有結構的數據類型(也可簡單的理解爲變量)的形式被保存在內存中。

內存是沒法永久保存數據的,當程序運行了一段時間,咱們斷電或者重啓程序,內存中關於這個程序的以前一段時間的數據(有結構)都被清空了。

在斷電或重啓程序以前將程序當前內存中全部的數據都保存下來(保存到文件中),以便於下次程序執行可以從文件中載入以前的數據,而後繼續執行,這就是序列化。

具體的來講,你玩使命召喚闖到了第13關,你保存遊戲狀態,關機走人,下次再玩,還能從上次的位置開始繼續闖關。或如,虛擬機狀態的掛起等。

2:跨平臺數據交互

序列化以後,不只能夠把序列化後的內容寫入磁盤,還能夠經過網絡傳輸到別的機器上,若是收發的雙方約定好實用一種序列化的格式,那麼便打破了平臺/語言差別化帶來的限制,實現了跨平臺數據交互。

反過來,把變量內容從序列化的對象從新讀到內存裏稱之爲反序列化,即unpickling。

如何序列化之json和pickle:

json

若是咱們要在不一樣的編程語言之間傳遞對象,就必須把對象序列化爲標準格式,好比XML,但更好的方法是序列化爲JSON,由於JSON表示出來就是一個字符串,能夠被全部語言讀取,也能夠方便地存儲到磁盤或者經過網絡傳輸。JSON不只是標準格式,而且比XML更快,並且能夠直接在Web頁面中讀取,很是方便。

JSON表示的對象就是標準的JavaScript語言的對象,JSON和Python內置的數據類型對應以下:

實踐

#json 序列化
import json
dic={'a':1}
x=None

res1=json.dumps(dic) #str(dic)
res2=str(dic)
print(res1,type(res1)) #json轉換後仍是字符串類型
#{"a": 1} <class 'str'>

print(res2,type(res2))
#{'a': 1} <class 'str'>

res=json.dumps(x)
print(res,type(res))
#null <class 'str'>

# json序列化
import json,time
user={'name':'egon','age':18,'nb':True}

#json.dumps
with open('user.json','w',encoding='utf-8') as f:
    f.write(json.dumps(user))
#user.json
#{"name": "egon", "age": 18, "nb": true}

students=['alex','egon','wxx','yxx']

#json.dump
json.dump(students,open('students.json','w',encoding='utf-8'))
#students.json
#["alex", "egon", "wxx", "yxx"]

# time.sleep(500)


# pickle序列化  能夠序列化因此python的類型
import pickle,json

s={1,2,3}
print(json.dumps(s))
#TypeError: Object of type 'set' is not JSON serializable  json不支持python獨有的數據結構

print(pickle.dumps(s))
#b'\x80\x03cbuiltins\nset\nq\x00]q\x01(K\x01K\x02K\x03e\x85q\x02Rq\x03.' 是一個byte類型

with open('s.pkl','wb') as f:
    f.write(pickle.dumps(s))

pickle.dump(s,open('s.pkl','wb'))


#json反序列化
import json

with open('user.json','r',encoding='utf-8') as f:
    user=json.loads(f.read()) #json.dumps
    print(user['name'])
#egon

user=json.load(open('user.json','r',encoding='utf-8'))
print(user['age'])
#18
print(user['nb'])
#True

json_str='{"count":1}'   #只要是json格式的字符串就能夠用json.loads來進行反序列化  #注意json格式不識別單引號、
print(json.loads(json_str)['count'])
#1

# json_str="{'count':1}"
# print(json.loads(json_str))


# print(json.load(open('user.json','r',encoding='utf-8')))


#pickle反序列化
import pickle

with open('s.pkl','rb') as f:
    s=pickle.loads(f.read())
    print(s,type(s))
#{1, 2, 3} <class 'set'>

s=pickle.load(open('s.pkl','rb'))
print(s, type(s))
#{1, 2, 3} <class 'set'>

 

六、shelve 模塊

shelve模塊比pickle模塊簡單,只有一個open函數,返回相似字典的對象,可讀可寫;key必須爲字符串,而值能夠是python所支持的數據類型

import shelve

f=shelve.open('db.shl')
f['stu1']={'name':'alex1','age':38}
f['stu2']={'name':'alex2','age':28}
f.close()



f = shelve.open("db.shl")
print(f["stu1"],type(f["stu1"]))
#{'name': 'alex1', 'age': 38} <class 'dict'>
print(f["stu2"],type(f["stu2"]))
#{'name': 'alex2', 'age': 28} <class 'dict'>
f.close()

 

七、xml模塊

示例文件

<data v="1.0">
    <country name="Liechtenstein">
        <rank updated="yes">2</rank>
        <year updated="yes">2010</year>
        <gdppc>141100</gdppc>
        <neighbor direction="E" name="Austria" />
        <neighbor direction="W" name="Switzerland" />
    </country>
    <country name="Singapore">
        <rank updated="yes">5
            <egon age="18" name="egon">egon is good</egon>
        </rank>
        <year updated="yes">2013</year>
        <gdppc>59900</gdppc>
        <neighbor direction="N" name="Malaysia" />
    </country>
    <country name="Panama">
        <rank updated="yes">69</rank>
        <year updated="yes">2013</year>
        <gdppc>13600</gdppc>
        <neighbor direction="W" name="Costa Rica" />
        <neighbor direction="E" name="Colombia" />
    </country>
</data>
View Code

實踐

from xml.etree import ElementTree

tree=ElementTree.parse('a.xml')

root=tree.getroot()
print(root)
#<Element 'data' at 0x1020b38b8>
print(root.tag) # 標籤的名字
#data
print(root.attrib)  #標籤的屬性
#{'v': '1.0'}
print(root.text)   #標籤的內容
#

#三種查找方式
#從子節點中找 只找一層
print(root.find('country'))  #只找一個
#<Element 'country' at 0x1005b39f8>

print(root.findall('country')) #找到全部符合的
#[<Element 'country' at 0x1005b39f8>, <Element 'country' at 0x101ab1188>, <Element 'country' at 0x101ab1368>]

print(root.find('rank'))  #沒有返回None
#None


#從整個樹形結構中查找  找全部層
print(list(root.iter('rank')))
#[<Element 'rank' at 0x102a4e408>, <Element 'rank' at 0x102a961d8>, <Element 'rank' at 0x102a963b8>]
print(list(root.iter('rank'))[0].tag)
#rank

for country in root.findall('country'):
    rank=country.find('rank')
    print(rank.tag,rank.attrib,rank.text)

#rank {'updated': 'yes'} 2
#rank {'updated': 'yes'} 5
#rank {'updated': 'yes'} 69


#遍歷文檔樹
for country in root:
    print('=============>',country.attrib['name'])
    for item in country:
        print(item.tag,item.attrib,item.text)

# =============> Liechtenstein
# rank {'updated': 'yes'} 2
# year {'updated': 'yes'} 2009
# gdppc {} 141100
# neighbor {'direction': 'E', 'name': 'Austria'} None
# neighbor {'direction': 'W', 'name': 'Switzerland'} None

# =============> Singapore
# rank {'updated': 'yes'} 5
# year {'updated': 'yes'} 2012
# gdppc {} 59900
# neighbor {'direction': 'N', 'name': 'Malaysia'} None

#.......



for year in root.iter('year'):
    print(year.tag,year.attrib,year.text)

# year {'updated': 'yes'} 2009
# year {'updated': 'yes'} 2012
# year {'updated': 'yes'} 2012

#修改
for year in root.iter('year'):
    year.set('updated',"yes") #添加屬性
    year.text=str(int(year.text)+1)  #寫入必須是str類型

tree.write('a.xml')  #把修改寫入文件 也可寫入寫文件  tree.write('b.xml')


#添加一個節點
for country in root:
    obj=ElementTree.Element('egon') #<egon name="egon" age="18">egon is good</egon>  #添加節點的標籤名
    obj.attrib={'name':'egon','age':'18'}  #添加節點的屬性  也可用set 
    # obj.set("name","egon")
    # obj.set("age","18")
    obj.text='egon is good'  #添加節點的內容
    country.append(obj)  #把新建的節點加入 country的標籤裏

tree.write('a.xml')  #把更改寫入文件

#指定寫入的標籤
for rank in root.iter('rank'):
    if int(rank.text) == 5:
        obj=ElementTree.Element('egon') #<egon name="egon" age="18">egon is good</egon>
        obj.attrib={'name':'egon','age':'18'}
        obj.text='egon is good'
        rank.append(obj)

tree.write('a.xml')

 

 八、configerparser模塊

[mysqld]
charater-server-set = utf8
default-engine = innodb
skip-grant-table = True
port = 3306
data_dir='C:\a\b\data'

[client]
user = root
password = alex3714

[egon]
name = egon
age = 18
View Code

示例

import configparser

config=configparser.ConfigParser()
config.read('my.ini')

print(config.sections()) #查看全部標題
#['mysqld', 'client', 'egon']

print(config.options('mysqld')) #查看某個標題下的全部選項
#['charater-server-set', 'default-engine', 'skip-grant-table', 'port', 'data_dir']

print(config.get('mysqld','charater-server-set')) #查看選項的值
#utf8

print(config.has_option('mysqld','aaa')) #查看配置是否存在
#False
if config.has_option('mysqld','aaa'):
    print(config.get('mysqld','aaa'))

print(config.getboolean('mysqld','skip-grant-table')) #獲得選項的布爾值
#True

print(config.getint('mysqld','port')) #獲得選項的整型
#3306

print(config.getfloat('mysqld','port')) #獲得選項的浮點型
#3306.0


config.add_section('egon') #添加一個標題 若存在報錯 #configparser.DuplicateSectionError: Section 'egon' already exists
config.set('egon','name','egon') #添加一個選項
config.set('egon','age','18')

config.set('client','password','alex3714') #更改

config.write(open('my.ini','w',encoding='utf-8'))
#把更改寫入文件

九、hashlib模塊

hash:一種算法 ,3.x裏代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
三個特色:
1.內容相同則hash運算結果相同,內容稍微改變則hash值則變
2.不可逆推
3.相同算法:不管校驗多長的數據,獲得的哈希值長度固定。

 

import hashlib
#哈希的兩種用途,一、加密(加密密碼) 二、校驗(以下載文件後和服務端的校驗)

m=hashlib.md5() #使用哈希中的md5算符
m.update('hello'.encode('utf-8')) #只接受bytes格式 不然報錯 TypeError: Unicode-objects must be encoded before hashing
m.update('world'.encode('utf-8')) #
print(m.hexdigest()) #獲得hash值  此時校驗的是 helloworld 。
#fc5e038d38a57032085441e7fe7010b0


# m=hashlib.md5()
# m.update('hello'.encode('utf-8'))
# m.update('world'.encode('utf-8'))
# print(m.hexdigest())
#
m1=hashlib.md5()
m1.update('hellowor'.encode('utf-8'))
m1.update('l'.encode('utf-8'))
m1.update('d'.encode('utf-8'))
print(m1.hexdigest())
#fc5e038d38a57032085441e7fe7010b0 和第一次獲得的值是同樣的


# name=input('user:>> ')
# pwd=input('password:>> ')
# m=hashlib.md5()
# m.update(pwd.encode('utf-8'))
# pwd=m.hexdigest()
#
# print(name,pwd)

cryt_pwd='aee949757a2e698417463d47acac93df'
pwds=[
    'alex3714',
    'alex123',
    '123alex'
]
def make_dic(pwds):
    dic={}
    for pwd in pwds:
        m=hashlib.md5(pwd.encode('utf-8')) #hashlib.md5能夠接受一次值
        dic[pwd]=m.hexdigest()
    return dic

dic=make_dic(pwds)
for pwd in dic:
    if dic[pwd] == cryt_pwd:
        print(pwd)

#alex3714

import hashlib
#加鹽
m=hashlib.sha512()
m=hashlib.md5('一行白鷺上青天'.encode('utf-8'))
m.update('alex3714'.encode('utf-8'))
m.update('兩個黃鸝鳴翠柳'.encode('utf-8'))
print(m.hexdigest())
#b018f53a1d2a6e85b3a750fd73123da7


import hmac #此模塊是有是必須加鹽
m=hmac.new('加鹽'.encode('utf-8'))
m.update('alex3714'.encode('utf-8'))
print(m.hexdigest())
#ec9cab331d1f5b632581562832eb368a

 

十、subprocess 模塊

import subprocess
import time

subprocess.Popen('uptime',shell=True) #第一個參數是字符串類型的命令,第二個參數是使用命令解釋器解釋第一個參數。程序並不會等待命令執行完畢,起一個子進程發送請求 因此會看到print的結果
print('----->主')
time.sleep(1)
#----->主
#22:44  up 9 days, 13:26, 12 users, load averages: 1.86 2.50 2.35


# import subprocess
import time
#
obj=subprocess.Popen('uptime',shell=True,
                 stdout=subprocess.PIPE, #正確輸出傳給PIPE管道    管道用的是一塊共享內存
                 stderr=subprocess.PIPE, #錯誤輸出傳給PIPE管道
                 )
print(obj)
#<subprocess.Popen object at 0x102a5f5c0>

print('第1次:',obj.stdout.read())  #此時會等待命令運行完成後返回的結果在執行後面的代碼  返回爲bytes格式的   此時須要用decode轉換成unicode bytes默認是系統的編碼。
#第1次: b'22:51  up 9 days, 13:33, 12 users, load averages: 2.76 2.54 2.34\n'
print('第2次:',obj.stderr.read())
#第2次: b''
print('---->主')
print('第1次:',obj.stdout.read()) #只能取一次值
#第1次: b''

obj=subprocess.Popen('cat a.txt',shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )
#print(obj.stdout.read())
#b'\xe6\xb5\x8b\xe8\xaf\x95'
print(obj.stdout.read().decode("utf-8"))
#測試





import subprocess #ls /etc ;pwdddd;ps aux   此時stdout和stderr都有結果
obj=subprocess.Popen('tasklist',shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

print(obj.stdout.read())
#b''
print(obj.stderr.read().decode("utf-8"))
#/bin/sh: tasklist: command not found

#瞭解
import subprocess #tasklist | findstr python
obj=subprocess.Popen('ps -ef | grep python',shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

print(obj.stdout.read().decode("utf-8"))
#501 40028 40023   0 11:06PM ??         0:00.00 /bin/sh -c ps -ef | grep python
#501 40030 40028   0 11:06PM ??         0:00.00 grep python


#第二種方式   模擬shell的管道 |
obj1=subprocess.Popen('ps -ef',shell=True,
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

obj2=subprocess.Popen('grep python',shell=True,
                 stdin=obj1.stdout,   #grep python 接收obj1 stdout輸出的結果
                 stdout=subprocess.PIPE,
                 stderr=subprocess.PIPE,
                 )

print(obj2.stdout.read().decode("utf-8"))
#501 40103 40094   0 11:09PM ??         0:00.01 grep python

 

2、面向對象基礎

一、類的定義與使用

'''
一、面向過程與面向對象
    面向過程:核心是過程二字,過程即解決問題的步驟,就是先幹什麼再幹什麼
    基於該思想寫程序就比如在設計一條流水線,是一種機械式的思惟方式
    優勢:複雜的過程流程化,進而簡單化
    缺點:擴展性差

    面向對象:核心是對象二字,對象是特徵與技能的結合體
    基於該思想編寫程序就比如在創造一個世界,世界是由一個個對象組成。
    優勢:可擴展性強
    缺點:編程複雜高,容易出現過分設計

二、類
    對象是特徵與技能的結合體,類就是一系列對象類似的特徵與技能的結合體
    在現實世界中:必定是先有的一個個具體存在的對象,後總結出的類
    在程序中:必定保證先定義類,後產生對象

三、站在老男孩學校的角度
現實中的對象:
    對象1:
        特徵
            學校=老男孩
            名字=李三炮
            性別=男
            年齡=18
        技能
            學習
            選課

    對象2:
        特徵
            學校=老男孩
            名字=張鐵蛋
            性別=女
            年齡=38
        技能
            學習
            選課

    對象3:
        特徵
            學校=老男孩
            名字=武大郎
            性別=男
            年齡=28
        技能
            學習
            選課

    對象4:
        特徵
            學校=老男孩
            名字=egon
            性別=男
            年齡=18
        技能
            教學


現實中的老男孩學生類:
    老男孩學生類
        類似的特徵
            學校=老男孩
        類似的技能
            學習
            選課

'''
# 類體代碼在類的定義階段就會馬上執行,
lass Student:
    school='oldboy'

    def learn(self):
        print('is learning')

    def choose_course(self):
        print('choose course')

    # print('====run')


print(Student)
#<class '__main__.Student'>
print(Student.__dict__)
#{'__module__': '__main__', 'school': 'oldboy', 'learn': <function Student.learn at 0x102247620>, 'choose_course': <function Student.choose_course at 0x1022476a8>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}

#查看
print(Student.school) #數據屬性
#oldboy
print(Student.learn) #函數屬性
#<function Student.learn at 0x102247620>

#增長
Student.country='China'
print(Student.country)
#China


#修改
Student.school='Oldboy'
print(Student.school)
#Oldboy

#刪除
del Student.country
#print(Student.country)

print(Student.learn)
#<function Student.learn at 0x102247620>
Student.learn('xxxxx')
#is learning

二、對象的定義與使用

class Student:
    school='oldboy'

    #stu1,'李三炮','男',18
    def __init__(self,name,sex,age): #在調用類時會自動觸發執行
        self.Name=name
        self.Sex=sex
        self.Age = age

        #stu1.Name='李三炮'
        #stu1.Sex='男'
        #stu1.Age=18

    def learn(self):
        print('is learning')

    def choose_course(self):
        print('choose course')

#調用類的過程又稱之爲實例化:stu1=Student('李三炮','男',18)
#一、獲得一個返回值,即對象,該對象是一個空對象stu1
#二、Student.__init__(stu1,'李三炮','男',18)


stu1=Student('李三炮','',18)
print(stu1.__init__)
#<bound method Student.__init__ of <__main__.Student object at 0x102a44940>>
print(stu1.__dict__)
#{'Name': '李三炮', 'Sex': '男', 'Age': 18}
print(stu1.Name,stu1.Age,stu1.Sex)
#李三炮 18 男

stu2=Student('張鐵蛋','',38)
stu3=Student('武大郎','',28)
print(stu2.__dict__)
#{'Name': '張鐵蛋', 'Sex': '女', 'Age': 38}
print(stu3.__dict__)
#{'Name': '武大郎', 'Sex': '男', 'Age': 28}
print(stu1,stu2,stu3)
#<__main__.Student object at 0x101a449b0> <__main__.Student object at 0x101a44a20> <__main__.Student object at 0x101a44a58>
print(stu2.Name)
#張鐵蛋

三、屬性的查找和綁定方法

x=1
class Student:
    school='oldboy'
    # Name='xxx'

    def __init__(self,name,sex,age): #在調用類時會自動觸發執行
        self.Name = name
        self.Sex = sex
        self.Age = age


        #stu1.Name='李三炮'
        #stu1.Sex='男'
        #stu1.Age=18

    def learn(self,x,y):
        print('%s is learning' %self.Name)
        print(x,y)

    def choose_course(self):
        print('choose course')

    def commit_hw():
        print('commit homework')

#一、查找一個對象的屬性順序是:先找對象本身的__dict__,再找類的__dict__
stu1=Student('李三炮','',18)
print(stu1.__dict__)
#{'Name': '李三炮', 'Sex': '男', 'Age': 18}
print(stu1.Name)
#李三炮
print(stu1.school)
#oldboy
#print(stu1.x)
#AttributeError: 'Student' object has no attribute 'x'

stu1=Student('李三炮','',18)
stu2=Student('張鐵蛋','',38)
stu3=Student('武大郎','',28)


# 二、類的數據屬性是全部對象共享,全部對象都指向同一個內存地址
stu1.school='xxx'
Student.school='Oldgirl'
print(Student.school,id(Student.school))
#Oldgirl 4339288416
print(stu1.school,id(stu1.school))
#xxx 4331010344
print(stu2.school,id(stu2.school))
#Oldgirl 4339288416
print(stu3.school,id(stu3.school))
#Oldgirl 4339288416

# 三、類中定義的函數是綁定給對象使用:
# 3.1:不一樣對象就是不一樣綁定方法
# 3.2:綁定給誰,就應該由誰來調用,誰來調用就會把誰當作第一個參數傳給對應的函數
print(Student.learn)
#<function Student.learn at 0x101a47730>
print(stu1.learn)
#<bound method Student.learn of <__main__.Student object at 0x101a44a58>>
print(stu2.learn)
#<bound method Student.learn of <__main__.Student object at 0x101a44a20>>
print(stu3.learn)
#<bound method Student.learn of <__main__.Student object at 0x101a44a90>>

stu1.learn(1,2) #Student.learn(stu1,1,2)
#李三炮 is learning
#1 2
stu2.learn(1,3)
# 張鐵蛋 is learning
# 1 3
stu3.learn(1,4)
#武大郎 is learning
#1 4
print(Student.learn)
#<function Student.learn at 0x102a27730>

#stu1.commit_hw()
#TypeError: commit_hw() takes 0 positional arguments but 1 was given

四、小練習

class Teacher:
    school='oldboy'
    count=0

    def __init__(self,name,sex,age,level,salary):
        self.name=name
        self.sex=sex
        self.age=age
        self.level=level
        self.salary=salary
        Teacher.count+=1

    def teach(self):
        print('%s is teaching' %self.name)

t1=Teacher('egon','male',18,10,3000)
t2=Teacher('alex','female',38,9,30000)
t3=Teacher('wxx','female',28,10,30000)

print(t1.count)
print(t2.count)
print(t3.count)
# 3
# 3
# 3


五、類即類型

l=[1,2,3,4] #l=list([1,2,3,4])
print(type(l))
#<class 'list'>
l1=list([1,2,3,4])
l2=list([1,2,3,4])
print(id(l1))
#4339305672
print(id(l2))
#4339305736

print(l1.append)
#<built-in method append of list object at 0x102a48cc8>
#l1.append(5) #list.appent(l1,5)
list.append(l1,5)
print(l1)
#[1, 2, 3, 4, 5]

六、對象之間的交互

class Garen:
    camp='demacia'
    def __init__(self,nickname,life_value,aggresivity):
        self.nickname=nickname
        self.life_value=life_value
        self.aggresivity=aggresivity

    def attack(self,enemy):
        enemy.life_value-=self.aggresivity


class Riven:
    camp = 'Noxus'

    def __init__(self, nickname, life_value, aggresivity):
        self.nickname = nickname
        self.life_value = life_value
        self.aggresivity = aggresivity

    def attack(self, enemy):
        enemy.life_value -= self.aggresivity

    def fire(self,enemy):
        enemy.life_value-=100

g1=Garen('草叢猥瑣男',1000,100)
r1=Riven('猛男雯雯',200,500)

print(r1.life_value)
#200
g1.attack(r1)
print(r1.life_value)
#100

 

七、從代碼級別看面向對象

#一、在沒有學習類這個概念時,數據與功能是分離的
def exc1(host,port,db,charset,sql):
    conn=connect(host,port,db,charset)
    res=conn.execute(sql)
    return res

def exc2(host,port,db,charset,proc_name)
    conn=connect(host,port,db,charset)
    res=conn.call_proc(prco_name)
    return res

#每次調用都須要重複傳入一堆參數
exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;')
exc2('127.0.0.1',3306,'db1','utf8','存儲過程的名字')

exc1('127.0.0.1',3306,'db1','utf8','select * from tb2;')

#二、在沒有學習類這個概念時,數據與功能是分離的
host='127.0.0.1'
port=3306
db='db1'
charset='utf-8'

x=1
y=2

def exc1(sql):
    conn=connect(host,port,db,charset)
    res=conn.execute(sql)
    return res

def exc2(proc_name)
    conn=connect(host,port,db,charset)
    res=conn.call_proc(prco_name)
    return res

def func1():
    print(x)
    print(y)

def func2():
    print(x)
    print(y)

#每次調用都須要重複傳入一堆參數
exc1('select * from tb1;')
exc2('utf8','存儲過程的名字')

exc1('select * from tb2;')

func()


class Mysqlhandle:
    def __init__(self,host,port,db,charset='utf-8'):
        self.host=host
        self.port=port
        self.db=db
        self.charset=charset
        self.conn=connect(host,port,db,charset)

    def exc1(self,sql):
        return self.conn.execute(sql)

    def exc2(self,proc_name)
        return self.conn.call_proc(prco_name)

obj1=Mysqlhandle('127.0.0.1',3306,'db1')

obj1.exc1('select * from t1')
obj1.exc1('select * from t2')
obj1.exc1('select * from t3')

obj2=Mysqlhandle('10.10.10.9',3306,'db2')
obj2.exc1('select * from t1 where id > 3')
相關文章
相關標籤/搜索