目錄python
編程語言是人類與計算機交流的介質git
編程就是程序員經過某種編程語言所編寫的一堆文件程序員
爲了讓計算機幫助人類工做算法
編程語言是用來和計算機交互的,可是計算機只認識0和1編程
直接和硬件交互(用0和1和計算機溝通)api
優勢:執行效率高網絡
缺點:開發效率低閉包
直接和硬件交互架構
優勢(相較於機器語言):開發效率高app
缺點(相較於機器語言):執行效率低
間接和計算機硬件交互
記錄下來,所有說完才能翻譯.文件編譯成另外一個obj文件.再和計算機溝通獲得結果,把代碼翻譯成機器語言,經過編譯器(彙編語言/機器語言寫的)
優勢(相較於解釋型語言):執行效率高
缺點(相較於解釋性語言):開發效率低
說一句翻譯一句
優勢(相較於編譯型語言):開發效率高
缺點(相較於編譯型語言):執行效率低
翻譯成機器語言,通常是經過解釋器(編譯型語言寫的)
咱們寫程序必定是程序運行的越快越好,咱們應該用編譯型
控制硬件
算術運算和邏輯運算
計算機只認識0和1(高低壓電頻)
優勢:速度快
缺點:斷點即消失
優勢:容量大,永久保存
缺點:速度慢
固態硬盤不須要平均延遲時間,RAM(斷電即消失) SSD(斷電不消失+算法(數學))基於電存儲
輸入信息,(鍵盤,鼠標等)
輸出信息, (顯示屏,打印機等)
輸入輸出信息,(U盤)
32位一次接受32個字節
64位一次接受64個字節
具備向下兼容性(好比說,64位兼容32位,32位不兼容64位)
開機就是告訴計算機操做系統的位置,存儲在CMOS存儲期內
你重裝系統的時候爲何要插U盤: 更改操做系統的路徑
機械硬盤上存儲的都是0和1
機械手臂: 讀取數據
磁道: 存儲數據
扇區: 多個磁道組成一塊,起始位置
尋找數據的時間:
平均延遲時間: 機械手臂到磁盤的時間 5ms (固態硬盤沒有這個時間)
平均尋數據的時間: (0 + 8.3) /2
7200r/min
文件是操做系統提供的虛擬單位
應用程序就是一大堆文件
操做系統本質仍是一個軟件
操做系統就是把對計算機的複雜指令簡單化(對CPU的指令)
應用程序依託於操做系統
操做系統依託於臨時操做系統
其餘的步驟都是如出一轍的
引用木桶效應(能夠百度)
由於網絡延遲遠遠大於程序的運行速度,這個時間能夠戶羅不計。
變量是用來描述世間萬物的狀態
height_of_nick = 150, 下劃線式
HeightOfNick = 150, 駝峯體
不變的量,常量本質上也是個變量,只不過變量名全大寫約定俗成爲了常量,之後不要去改變他
有n個變量名指向一個變量值A,則A的引用計數爲n
當變量的引用計數爲0的時候,python解釋器會自動回收該變量的內存空間
[-5, 256]之間,當python解釋器打開的時候就已經開闢內存空間存在,不會受垃圾回收機制影響
優勢:運行一句執行語句
缺點:關閉即消失
優勢: 一直存在
缺點:所有寫完才能調試BUG
交叉賦值
x, y = y,x
鏈式賦值
x=y=z= 10
解釋 ; 讓代碼在python解釋器運行的時候不被解釋,即讓他無心義
單行註釋: '使用單引號' 多行註釋: ''' 可 以 換 行 '''
數據類型: 不一樣種類的變量值用不一樣的數據類型描述
age = 18;age = int(18);int('18')
age = 18;age1 = 19 # 不建議使用 print(age,age1) age,age1 = 18,19 # 解壓縮
+-*/ % // **
( a = 1log
方法,導入import cmath
庫年齡/身份證號碼/身高/體重等
salary=3.2;salary=float(3.2);float('3.2')
+-*/ % // **
( a = 1log
方法,導入import cmath
庫能夠用來表示薪水等
name = 'nick';name = "nick" name = str('nick') name = ''' nick nick ''' name = """ nick nick """ x = str(10) # '10'
s1 = 'nick' s2 = 'handsome' s1 + s2 s3 = 10 # nickhandsome s1 + str(10) # nick10 # int(s1) + s3 s1 * 5 # 'nicknicknicknicknick'
ctrl+鼠標左鍵 進入源碼模式
nick_info = ['nick',180,140,['read','run','music']] nick_info[-1][1] # 'run' # 僅作了解 lis = [1,2,3] lis2 = [4,5,6] print(lis+lis2) print(lis*2) # [1, 2, 3, 1, 2, 3]
nick_info_dict = {'name':'nick','height':180} nick_info_dict['height']
除了0/None/空/False以外全部的數據類型(全部你能看到的東西)都自帶布爾值爲True
一次性取多個值,解壓縮的對象有多少個元素,則必須拿多少個
lis = [1,2,3] x1,x2,x3 = lis # 1,2,3 # 不會用 x1,_,x3 = lis # 1,_,3 *_,x3 = lis # _,_,3
input() # 等待用戶輸入,若是用戶不輸入,程序不會結束運行 input接收的值不管如何都是字符串 ''' x = input('請輸入你想要的輸入的數字:') print(type(x)) print(x) x = int(x) + 1 # x = eval(x) # 除了字符串之外均可以轉換,不建議使用 print(x) '''
raw_input() # 與用戶交互和python3中的input如出一轍 input() # 與用戶交互,必須得指定輸入的類型,輸入什麼類型拿到什麼類型
name = 'nick' print('name:{}'.format(name))
name = 'nick' print(f'name:{name}') # :.2f 保留兩位小數
+-*/ % // **
= += -= *= /= %= //= **=
> >= < <= == !=
(A is not B == not A is B)
''' if <條件>: <代碼塊> '''
僞代碼: 大概知道代碼的意思,可是這種代碼沒法運行
''' if <條件>: <代碼塊1> else: <代碼塊2> '''
''' if <條件1>: <代碼塊1> elif <條件2>: <代碼塊2> ... else: <代碼塊3> '''
''' if <條件1>: if <條件2>: <代碼塊> '''
if 條件: # TODO pass
不可控, 循環一切
跳出本層循環,跳出循環
跳出本次循環
循環沒有被break終止纔會執行
可控, 循環容器類型元素 + 字符串(可迭代數據類型)
0,1,2,3,4,5,6,7,8,9 10 .....99 100 1000 10000
0 1 10 11 100
10101
$$
2^41 + 2^30 + 2^21 + 2^10 + 2^0*1 = 21
$$
低電壓表示 0
高電壓表示 1
低高低高
0101 a
x = 10
, x = int('10')
x = 10.1
, x = float('10.1')
name = 'nick' # \n 換行 # \t 縮進,4個空格 # \r+end='' 覆蓋上一次打印 name = r'\n\ta' # 取消\n和\t的做用 name = '\\n\\ta' # 取消\n和\t的做用
有索引的就是有序,無索引的就是無序
值變id不變的是可變類型;值變id變的是不可變
1. 定義方式: {}內以逗號隔開多個元素(不能爲可變數據類型)
條件判斷後觸發,通常不單獨使用
age = 18 # 答案 count = 0 # 遊戲次數控制 prize_dict = {0: '布娃娃', 1: '變形金剛', 2: '奧特曼', 3: '<Python從入門到放棄>'} # 核心代碼 while count < 3: inp_age = input('請輸入你的年齡>>>') # 與用戶交互 # 判斷用戶是否騷擾(超綱:判斷用戶輸入的是否爲數字) if not inp_age.isdigit(): print('傻逼,你的年齡輸錯了') continue inp_age_int = int(inp_age) # 核心邏輯,判斷年齡 if inp_age_int == age: print('猜對了') print(prize_dict) # 打印獎品 # 獲取兩次獎品 for i in range(2): prize_choice = input( '請輸入你想要的獎品,若是不想要,則輸入"n"退出!!!') # 與用戶交互獲取獎品 # 判斷是否須要獎品 if prize_choice != 'n': print(f'恭喜你得到獎品: {prize_dict[int(prize_choice)]}') else: break break elif inp_age_int < age: print('猜小了') else: print('猜大了') count += 1 # 成功玩一次遊戲 if count != 3: continue again_choice = input('是否繼續遊戲,繼續請輸入"Y",不然任意鍵直接退出.') # 交互是否再一次 # 判斷是否繼續 if again_choice == 'Y': count = 0
深淺拷貝只針對可變類型
lt = [1,2,3,[4,5,6]] lt2 = lt # 當lt2爲lt的拷貝對象時,lt內部任意數據類型的對象變化,lt2都變化
lt = [1,2,3,[4,5,6]] import copy lt2 = copy.copy(lt) # lt2 = lt.copy() # 當lt2爲lt的淺拷貝對象時,lt內部可變數據類型變化,lt2也隨之變化;lt內部不可變數據類型變化,lt2不變
lt = [1,2,3,[4,5,6]] import copy lt2 = copy.deepcopy(lt) # 當lt2爲lt的深拷貝對象時,lt內部任意數據類型的對象變化,lt2都不變化
try: 1/0 except Exception as e: print(e) finally: print(1) # assert assert 1 == 1 # 知足條件跳過這一行 ; 不知足報錯 # raise raise 錯誤類型() # 拋出異常
可變 | 不可變 |
---|---|
列表/字典/集合 | 整型/浮點型/字符串/元組 |
有序 | 無序 |
---|---|
字符串/列表/元組 | 字典/集合 |
一個值 | 多個值 |
---|---|
整型/浮點型/字符串 | 列表/元組/字典/集合 |
# 1. 打開文件 f = open(file_path, 'r') # 2. 讀寫操做 f.read() / f.write() # 3. 關閉文件 f.close()
二進制和字符之間的轉換過程 --> 字符編碼
ascii,gbk,shit,fuck 每一個國家都有本身的編碼方式
美國電腦內存中的編碼方式爲ascii ; 中國電腦內存中的編碼方式爲gbk , 美國電腦沒法識別中國電腦寫的程序 , 中國電腦沒法識別美國電腦寫的程序
如今硬盤中躺着 ascii/gbk/shit/fuck 編碼的文件, 他們的編碼格式已經沒法修改了, 因此內存中出現unicode編碼, 內存中的unicode編碼方式能夠識別 ascii/gbk/shit/fuck 編碼的文件
用unicode編碼方式運行了 ascii/gbk/shit/fuck 編碼的文件, 最後仍是要裝入硬盤, 裝入硬盤早期用unicode存進去,可是 他在識別ascii的時候, 會把8位數字轉換成16位數字存入硬盤, 浪費空間, 因此出現了utf8(與unicode對應,而且壓縮unicode編碼的字符)
utf8 能識別其餘國家的編碼,只識別unicode, utf8目前還不能放在內存,. 可是如今寫的代碼都是utf8, 歷史遺留ascii/gbk/shit/fuck 編碼的文件早晚消失/淘汰,要麼被轉換成utf8格式.因此早晚有一天內存中也是utf8.
代碼詳情 | Python2執行狀況 | Python3執行狀況 |
---|---|---|
coding:gbk print('中') 終端:utf8 |
亂碼 | 不亂碼 |
coding:utf8 print('中') 終端:utf8 |
不亂碼 | 不亂碼 |
coding:gbk print(u'中') 終端:utf8 |
不亂碼 | 不亂碼 |
coding:utf8 print(u'中') 終端:utf8 |
不亂碼 | 不亂碼 |
用文件指定的編碼方式存儲定義後的變量
若是文件指定編碼爲'gbk' ,那就會以gbk的形式存儲變量, 原本打印的是0和1,可是終端會自動對你的0和1安裝終端默認的編碼轉換成字符 ,若是終端的默認編碼是utf8 ,亂碼; 若是終端默認編碼是gbk,不亂嗎
若是定義變量前加上u,coding:xxx不會對他形成任何影響, 由於會用unicode編碼存儲變量, 終端是任何類型的編碼均可以識別
用unicode編碼方式存儲定義後的變量
之後寫文件以什麼格式存儲,就以什麼格式讀取
r : 只讀
f.read()
w: 清空後寫入(文件不存在自動建立)
f.write()
a: 追加(文件不存在自動建立)
f.write()
文本模式:t
二進制模式:b
t/b沒法單獨使用,只能和r/w/a一塊兒使用
with open() as f: # 自動關閉
pip instlal pyinstaller
切換路徑到文件夾(文件夾包含img.ico和test.py這兩個文件)
pyinstaller -i img.ico -F test.py
with open('test.py','r',encoding='utf8') as fr,\ open('test_swap.py','w',encoding='utf8') as fw: data = fr.read() # data邏輯修改 fw.write(data) import os os.remove('test.py') os.rename('test_swap.py','test.py')
with open('test.py','r',encoding='utf8') as fr,\ open('test_swap.py','w',encoding='utf8') as fw: for i in fr: # i邏輯修改 fw.write(i) import os os.remove('test.py') os.rename('test_swap.py','test.py')
def 函數名(參數1,參數2,...): return 返回值
沒有參數的函數
有參數的函數
pass
return 除了能返回值 ,終止函數
返回多個值,用元組形式返回
函數名()
具備描述意義
從左到右一個一個寫
位置形參具備默認值, 默認形參必須在位置形參後面
具體的數據類型
從左到右一個一個給形參傳值
按照形參名傳值, 關鍵字實參在位置實參後面
*args用元組的形式接收多餘的位置實參,
打散元組而後將打散的值一個一個傳值給形參
**kwargs用字典的形式接收多餘的關鍵字實參
打散字典而後將打散的值傳給形參
dic = {'a':1,'b':2} a=1,b=2
函數內套函數
def f1(): def f2(): pass
命名空間是用來組織和重用代碼的。
python解釋器啓動的時候生成,如 len/int/dict
文件執行的時候生成
函數調用的時候生成
內置-->全局-->局部
從當前開始 --> 局部-->全局-->內置
全局+內置空間定義的變量
x = 1 def f1(): x = 3 f1() print(x) # 1 x = 1 和 x = 3的兩個x毫無關係
局部空間定義的變量,不一樣的函數具備不一樣的做用域
def f1(): x = 1 def f2(): x = 3 print(x) f1() # 1 x = 1 和 x = 3的兩個x毫無關係
全局做用域內的變量和局部做用域內的變量就算變量名相同也毫無關係 ; 不一樣函數的局部做用域內的變量就算變量名相同也毫無關係
(全局) x = 1 def f1(): global x x = 3 f1() print(x) # 3
(局部) def f1(): x = 1 def f2(): nonlocal x x = 3 print(x) f1() # 3
lt = [1,2,3] def f1(): lt.append(4) f1() print(lt) # [1,2,3,4]
內置--》全局--》局部
做用域:
內置和全局 --》 全局做用域
局部 --> 局部做用域
x = 1 def func(): x = 3 func() print(x) # 1
def f1(): x = 1 def f2(): x = 3 f2() print(x) f1() # 1
把函數A和變量x 包在一個函數B內部, 而後經過函數B的返回值 把函數A和變量x 共同返回出來
x = 1 def f1(): print(x) x = 2 f1() # 若是不使用閉包,可能出現這種狀況,全局變量的變化會影響函數值 # def f2(): # x = 100 # # def f1(): # print(x) # # return f1 # # x = 2 # # f = f2() # f = f1 # 不受外界變量的影響了 # # print(f'f.__closure__[0].cell_contents: {f.__closure__[0].cell_contents}') # 閉包函數f的閉包元素 # f() # f1() def f2(x): def f1(): print(x) return f1 x = 2 f_100 = f2(100) # f = f1 # 不受外界變量的影響了 f_100() # f1() f_100() # f1() f_100() # f1() f_200 = f2(200) f_200() f_200() f_200() f_200()
# 裝飾器:裝飾的一個函數,寫裝飾器就是寫函數,裝飾一個函數 # 1. 被裝飾的函數不能改變其調用方式 # 2. 被裝飾的函數不能改變其源代碼 import time # start = time.time() # index() # end = time.time() # print(end - start) # 裝飾器 # def index(): # start = time.time() # index() # end = time.time() # print(end - start) # 完整的兩層裝飾器, 三層裝飾器就是給兩層加參數 def sanceng(engine): def outter(func): def wrapper(*args, **kwargs): # 形參 if engine == 'file': start = time.time() res = func(*args, **kwargs) # 原始的index # 實參 end = time.time() print(end - start) return res elif engine == 'db': res = func(*args, **kwargs) return res return wrapper return outter @sanceng('file') def index(x): print(x) print('from index') return 123 # outter = sanceng('db') # outter = outter # index = outter(index) # index = wrapper index(1) # wrapper() def outter(func): def wrapper(*args,**kwargs): res = func(*args,**kwargs) return res return wrapper @outter def index(x): print('from index') def sanceng(engine): def outter(func): def wrapper(*args, **kwargs): res = func(*args, **kwargs) return res return wrapper return outter @sanceng('file') def index(x): print('from index')
可迭代對象: 具備iter方法的對象, 可迭代對象不必定是迭代器對象 迭代器對象: 具備iter和next方法的對象, 迭代器對象必定是可迭代對象,迭代器對象必定是可迭代對象, 迭代器對象加上iter方法仍是迭代器自己 for 循環原理 for i in lt: print(i) 1. 把lt變成迭代器對象 1. 而後迭代使用__next__方法獲取每個元素 1. 捕捉異常中斷while循環 # 不依賴索引迭代取值
取代了if...else
一行實現列表生成
[i for i in range(10000000)]
一行實現字典生成
{ k:v for k,v in dic.items()}
節省內存空間,生成器不使用next方法不會取值的(一隻老母雞),而列表全取完展示給你(一筐雞蛋)
(i for i in range(1000000))
帶有yield關鍵字的函數
def func(): yield 1 print(2) yield 3 g = func() # g是生成器, 具備iter和next方法,生成器就是迭代器對象 for i in g: print(i)
yield:
1. 暫停函數,下一次next會運行上一個yield的下面的代碼
return:
1. 終止函數
匿名函數,他沒有綁定名字,使用一次即被收回,加括號既能夠運行。
沒有名字的函數, 不單獨使用
# f = lambda x:x+1 # f(1)
和max/min/filter/sorted/map聯用
遞歸的核心: 遞進的時候可以達到一個結果,問題規模愈來愈小(不必定要真正的達到); 設置一個條件,可以讓最後一次函數調用結束;
遞歸是函數調用函數自己,而後有結束條件
遞歸代碼(遞歸更多的是一種思想,用來解決某種問題)
count = 1 # 2 # 3 def f1(): global count # 下面的count是全局的count if count > 100: return count += 1 # 2 # 3 print(count) # 2 # 3 f1() f1()
直接調用:直接調用指的是:直接在函數內部調用函數自身。
間接調用:間接調用指的是:不在原函數體內調用函數自身,而是經過其餘的方法間接調用函數自身。
遞歸必需要有兩個明確的階段:
遞歸的精髓在於經過不斷地重複逼近一個最終的結果。
遞歸的使用方法:
參考二分法:
簡單來講就是在一列數裏邊一直從中間截斷,而後看須要的數字在那邊就保留那邊知道只剩那個須要的數。
1.bytes()
解碼字符。
res = '你好'.encode('utf8') print(res) b'\xe4\xbd\xa0\xe5\xa5\xbd' res = bytes('你好', encoding='utf8') print(res) b'\xe4\xbd\xa0\xe5\xa5\xbd'
2.chr()/ord()
chr()參考ASCII碼錶將數字轉成對應字符;ord()將字符轉換成對應的數字。
print(chr(65)) A print(ord('A')) 65
3.divmod()
分欄。
print(divmod(10, 3)) (3, 1)
4.enumerate()
帶有索引的迭代。
l = ['a', 'b', 'c'] for i in enumerate(l): print(i) (0, 'a') (1, 'b') (2, 'c')
5.eval()
把字符串翻譯成數據類型。
lis = '[1,2,3]' lis_eval = eval(lis) print(lis_eval) [1, 2, 3]
6.hash()
是否可哈希。
print(hash(1)) 1
1.abs()
求絕對值。
print(abs(-13)) # 求絕對值 13
2.all()
可迭代對象內元素全爲真,則返回真。
print(all([1, 2, 3, 0])) print(all([])) False True
3.any()
可迭代對象中有一元素爲真,則爲真。
print(any([1, 2, 3, 0])) print(any([])) True False
4.bin()/oct()/hex()
二進制、八進制、十六進制轉換。
print(bin(17)) print(oct(17)) print(hex(17)) 0b10001 0o21 0x11
5.dir()
列舉出全部time的功能。
import time print(dir(time)) ['_STRUCT_TM_ITEMS', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'altzone', 'asctime', 'clock', 'ctime', 'daylight', 'get_clock_info', 'gmtime', 'localtime', 'mktime', 'monotonic', 'perf_counter', 'process_time', 'sleep', 'strftime', 'strptime', 'struct_time', 'time', 'timezone', 'tzname', 'tzset']
6.frozenset()
不可變集合。
s = frozenset({1, 2, 3}) print(s) frozenset({1, 2, 3})
7.globals()/loacals()
查看全局名字;查看局部名字。
# print(globals()) def func(): a = 1 # print(globals()) print(locals()) func() {'a': 1}
8.pow()
print(pow(3, 2, 3)) # (3**2)%3 0
9.round()
print(round(3.5)) 4
10.slice()
lis = ['a', 'b', 'c'] s = slice(1, 4, 1) print(lis[s]) # print(lis[1:4:1]) ['b', 'c']
11.sum()
print(sum(range(100))) 4950
12.__import__()
經過字符串導入模塊。
m = __import__('time') print(m.time()) 1556607502.334777
面向過程編程是解決問題的一種思想,面向過程編程,核心是編程二字,過程指的是解決問題的步驟,即先幹什麼、後幹什麼、再幹什麼、而後幹什麼……
能夠將面向過程編程想象成工廠流水線,循序漸進的運行。
優勢:複雜的問題流程化,進而簡單化
缺點:擴展性差。
'''
1.註冊 2.登陸 3.查看額度 4.提現 5.還款 6.轉帳 7.查看流水 8.購物功能 9.查看購物車 10.註銷 q.退出
一個項目是如何從無到有:
1.需求分析:
2.程序的架構設計 用戶視圖層: 用戶與程序交互的. 小的邏輯判斷 接口層: 業務邏輯的處理 數據層: 對數據進行存\取 不設計程序架構的問題: 1.邏輯不清晰 2.結構不清晰 3.不便於維護 設計程序的好處: 1.邏輯清晰 2.結構清晰 3.便於維護 4.程序的解耦合 3.分任務開發 項目經理: 把開發任務分發給開發人員: 提升項目開發效率 較少項目開發週期 4.測試: 黑盒測試: 對用戶能看到的操做,進行測試. 白盒測試: 對程序的性能進行測試. 5.上線運行 交給運維人員部署上線,運營.