python基礎篇(完整版)

目錄python

計算機基礎之編程和計算機組成

什麼是編程語言

編程語言是人類與計算機交流的介質git

什麼是編程

編程就是程序員經過某種編程語言所編寫的一堆文件程序員

爲何要編程

爲了讓計算機幫助人類工做算法

編程語言的分類

編程語言是用來和計算機交互的,可是計算機只認識0和1編程

機器語言(低級語言)

直接和硬件交互(用0和1和計算機溝通)api

優勢:執行效率高網絡

缺點:開發效率低閉包

彙編語言

直接和硬件交互架構

優勢(相較於機器語言):開發效率高app

缺點(相較於機器語言):執行效率低

高級語言

編譯型

間接和計算機硬件交互

記錄下來,所有說完才能翻譯.文件編譯成另外一個obj文件.再和計算機溝通獲得結果,把代碼翻譯成機器語言,經過編譯器(彙編語言/機器語言寫的)

優勢(相較於解釋型語言):執行效率高

缺點(相較於解釋性語言):開發效率低

解釋型

說一句翻譯一句

優勢(相較於編譯型語言):開發效率高

缺點(相較於編譯型語言):執行效率低

翻譯成機器語言,通常是經過解釋器(編譯型語言寫的)

咱們寫程序必定是程序運行的越快越好,咱們應該用編譯型

計算機的五大組成

CPU(至關於人類的大腦)

多核CPU(多個大腦,同時(同一時刻)處理多件事情)

控制器

控制硬件

運算器

算術運算和邏輯運算

內存

計算機只認識0和1(高低壓電頻)

優勢:速度快

缺點:斷點即消失

外存

優勢:容量大,永久保存

缺點:速度慢

固態硬盤

固態硬盤不須要平均延遲時間,RAM(斷電即消失) SSD(斷電不消失+算法(數學))基於電存儲

輸入設備

輸入信息,(鍵盤,鼠標等)

輸出設備

輸出信息, (顯示屏,打印機等)

IO設備(輸入輸出設備)

輸入輸出信息,(U盤)

應用程序的啓動流程

  1. 雙擊qq(快捷方式-->指向了一個路徑(外存)), 實際上是去這個位置找到qq內容
  2. CPU再發送指令給內存,讓內存讀取外存中的qq內容
  3. 運行

32位和64位等區別

32位一次接受32個字節

64位一次接受64個字節

具備向下兼容性(好比說,64位兼容32位,32位不兼容64位)

ROM存儲器+CMOS存儲器

開機就是告訴計算機操做系統的位置,存儲在CMOS存儲期內

你重裝系統的時候爲何要插U盤: 更改操做系統的路徑

硬盤工做原理

機械硬盤上存儲的都是0和1

機械手臂: 讀取數據

磁道: 存儲數據

扇區: 多個磁道組成一塊,起始位置

尋找數據的時間:

平均延遲時間: 機械手臂到磁盤的時間 5ms (固態硬盤沒有這個時間)

平均尋數據的時間: (0 + 8.3) /2

7200r/min

操做系統

什麼是文件

文件是操做系統提供的虛擬單位

什麼叫應用程序

應用程序就是一大堆文件

什麼是操做系統

操做系統本質仍是一個軟件

操做系統的做用

操做系統就是把對計算機的複雜指令簡單化(對CPU的指令)

操做系統啓動

  1. 開機
  2. 啓動一個臨時操做系統(只作啓動操做系統的事情)
  3. 而後臨時操做系統會去讀取操做系統的路徑地址(特殊的CMOS硬件)
  4. 啓動真正的操做系統

應用程序和操做系統啓動的區別

應用程序依託於操做系統

操做系統依託於臨時操做系統

其餘的步驟都是如出一轍的

網絡瓶頸效應

引用木桶效應(能夠百度)

由於網絡延遲遠遠大於程序的運行速度,這個時間能夠戶羅不計。

變量

什麼事變量

變量是用來描述世間萬物的狀態

變量的組成

  1. 變量名:接收變量值
  2. 賦值符號:把變量值賦值給變量名
  3. 變量值:就是一個數值

變量名的命名規範

  1. 變量名由數字/字母/下劃線組成,不能以數字開頭
  2. 變量名不能以關鍵字命名
  3. 變量名具備意義

變量名的兩種定義方式

height_of_nick = 150, 下劃線式

HeightOfNick = 150, 駝峯體

定義變量的三個特徵

  1. 打印變量值
  2. 打印變量的內存地址
  3. 打印變量的數據類型

常量

不變的量,常量本質上也是個變量,只不過變量名全大寫約定俗成爲了常量,之後不要去改變他

python內存管理方式

引用計數

有n個變量名指向一個變量值A,則A的引用計數爲n

垃圾回收機制

當變量的引用計數爲0的時候,python解釋器會自動回收該變量的內存空間

小整數池

[-5, 256]之間,當python解釋器打開的時候就已經開闢內存空間存在,不會受垃圾回收機制影響

執行python的兩種方式

交互式

優勢:運行一句執行語句

缺點:關閉即消失

命令行式

優勢: 一直存在

缺點:所有寫完才能調試BUG

花式賦值

交叉賦值
x, y = y,x

鏈式賦值
x=y=z= 10

註釋

解釋 ; 讓代碼在python解釋器運行的時候不被解釋,即讓他無心義

單行註釋:
  '使用單引號'
多行註釋:
'''
可
以
換
行
'''

數據類型基礎

數據類型: 不一樣種類的變量值用不一樣的數據類型描述

數字類型

整形(int)

  1. 定義方式: age = 18;age = int(18);int('18')
age = 18;age1 = 19  # 不建議使用
print(age,age1)

age,age1 = 18,19  # 解壓縮
  1. 做用: 描述年齡/id號等
  2. 使用方式:+-*/ % // **( a = 1
    b = 2
    print(a+b)
    print(b-a)
    print(a*b)
    print(a/b)
    print(a//b) # 取整
    print(a%b) # 取餘
    print(a**b) # 冪)
  3. 若是使用log方法,導入import cmath

做用

年齡/身份證號碼/身高/體重等

浮點型(float)

  1. 定義方式:salary=3.2;salary=float(3.2);float('3.2')
  2. 做用:描述薪資等
  3. 使用方法:+-*/ % // **( a = 1
    b = 2
    print(a+b)
    print(b-a)
    print(a*b)
    print(a/b)
    print(a//b) # 取整
    print(a%b) # 取餘
    print(a**b) # 冪)
  4. 若是使用log方法,導入import cmath

做用:

能夠用來表示薪水等

字符串類型

  1. 定義方式:
name = 'nick';name = "nick"
name = str('nick')
name = '''
nick
nick
'''
name = """
nick
nick
"""


x = str(10) # '10'
  1. 做用: 名字等
  2. 使用方法
s1 = 'nick'
s2 = 'handsome'

s1 + s2

s3 = 10  # nickhandsome
s1 + str(10)  # nick10
# int(s1) + s3


s1 * 5  # 'nicknicknicknicknick'

列表

  1. 定義方式: []內用逗號隔開多個元素(全部數據類型)

ctrl+鼠標左鍵 進入源碼模式

  1. 做用: 存儲多個值
  2. 使用方法
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]

字典

  1. 定義方式: {}內以逗號隔開鍵值對 key(通常爲字符串,具備描述意義):value(爲任意數據類型) # 哈希表
  2. 做用: 存儲多個值,不依賴索引取值,而經過key取值
  3. 使用方法
nick_info_dict = {'name':'nick','height':180}

nick_info_dict['height']

布爾類型

  1. True和False,通常只在條件判斷的時候

除了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)
'''

python2中的與用戶交互

raw_input()  # 與用戶交互和python3中的input如出一轍



input()  # 與用戶交互,必須得指定輸入的類型,輸入什麼類型拿到什麼類型

三種格式化輸出

佔位符

  1. %s 匹配全部數據類型的字符
  2. %d 只匹配數字

format格式化

name = 'nick'

print('name:{}'.format(name))

f-string格式化

name = 'nick'

print(f'name:{name}')


# :.2f 保留兩位小數

基本運算符

算術運算符

+-*/ % // **

邏輯運算符

  1. and: 兩個條件都爲真,即爲真,不然都爲假
  2. or:兩個條件其中一個爲真,則爲真,不然都爲假
  3. not: 真變假,假變真

賦值運算符

= += -= *= /= %= //= **=

比較運算符

> >= < <= == !=

身份運算符

  1. is: 比較兩個變量的id
  2. is not: 比較兩個變量的id(A is not B == not A is B)

運算符的優先級(瞭解)

  1. 若是你要優先運算,加括號

流程控制之if判斷

單分支結構

'''
if <條件>:
    <代碼塊>
'''

僞代碼: 大概知道代碼的意思,可是這種代碼沒法運行

雙分支結構

'''
if <條件>:
    <代碼塊1>
else:
    <代碼塊2>
'''

多分支結構

'''
if <條件1>:
    <代碼塊1>
elif <條件2>:
    <代碼塊2>
...
else:
    <代碼塊3>
'''

if判斷的嵌套

'''
if <條件1>:
    if <條件2>:
        <代碼塊>
'''
if 條件:
    # TODO
    pass

while循環

不可控, 循環一切

while + break

跳出本層循環,跳出循環

while + continue

跳出本次循環

while + else

循環沒有被break終止纔會執行

for循環

可控, 循環容器類型元素 + 字符串(可迭代數據類型)

for + break

for + continue

for + else

進制轉換

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

數值類型內置方法

整型

  1. 做用:描述年齡,id
  2. 定義方式: x = 10, x = int('10')
  3. 使用方法: 算術運算 和 比較比較運算
  4. 有序無序: 壓根沒有這一說
  5. 存一個值仍是多個值:一個值
  6. 可變仍是不可變: 不可變

浮點型

  1. 做用:描述薪資
  2. 定義方式: x = 10.1, x = float('10.1')
  3. 使用方法: 算術運算 和 比較比較運算
  4. 有序無序: 壓根沒有這一說
  5. 存一個值仍是多個值:一個值
  6. 可變仍是不可變: 不可變

字符串類型內置方法

  1. 做用: 描述姓名,性別
  2. 定義方法
name = 'nick'

# \n 換行
# \t 縮進,4個空格
# \r+end='' 覆蓋上一次打印

name = r'\n\ta'   # 取消\n和\t的做用
name = '\\n\\ta'  # 取消\n和\t的做用
  1. 內置方法
    1. 優先掌握
      1. 索引取值
      2. 切片
      3. strip
      4. split
      5. len長度
      6. 成員運算
      7. for 循環
    2. 須要掌握
      1. upper/lower
      2. startswith/endswith
      3. rstrip/lstrip
      4. rsplit
      5. isdigit/isalpha
      6. join
      7. replace
    3. 瞭解
      1. find/rfind/index/rindex/count
      2. capitalize/swapcase/title
      3. center/ljust/rjust/zfill
      4. is系列(真正的瞭解)
    4. 存一個值仍是多個值:一個值
    5. 有序or無序:有序
    6. 可變仍是不可變:不可變

有序or無序

有索引的就是有序,無索引的就是無序

可變or不可變

值變id不變的是可變類型;值變id變的是不可變

列表list

  1. 定義方式: []內逗號隔開多個元素(任意數據類型)
  2. 使用方法
    1. 優先掌握
      1. 索引取值,索引修改值
      2. 切片
      3. 成員運算
      4. 長度
      5. for循環
      6. append
      7. del刪除
    2. 須要掌握
      1. insert
      2. pop
      3. remove
      4. count
      5. find
      6. index
      7. extend
      8. sort
      9. reverse
      10. clear
      11. copy
      12. ...

字典dict

  1. 定義方式: {}內以逗號隔開鍵值對,key(具備描述意義,不能爲可變數據類型):value(具體的任意數據類型)
  2. 使用方法
    1. 優先掌握
      1. 按key取值,按key修改值,按key增長值
      2. 成員運算
      3. 長度
      4. for循環
      5. keys/values/items
      6. del 刪除
      7. get
    2. 須要掌握
      1. copy
      2. update
      3. clear
      4. setdefault
      5. fromkeys
      6. pop(按key刪除)
      7. popitem(隨機刪除,可是刪除最後一個)

元組tuple

  1. 定義方式: ()內以逗號隔開多個任意數據類型的元素
  2. 不可更改的列表,建立後就只能是那樣了

集合set

1. 定義方式: {}內以逗號隔開多個元素(不能爲可變數據類型)
  1. 使用方法:

布爾類型bool

  1. True
  2. False

條件判斷後觸發,通常不單獨使用

1、Python基礎實戰之猜年齡遊戲

  1. 給定年齡,用戶能夠猜三次年齡
  2. 年齡猜對,讓用戶選擇兩次獎勵
  3. 用戶選擇兩次獎勵後能夠退出
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 錯誤類型()  # 拋出異常

數據類型分類

可變or不可變

可變 不可變
列表/字典/集合 整型/浮點型/字符串/元組

有序or無序

有序 無序
字符串/列表/元組 字典/集合

一個值or多個值

一個值 多個值
整型/浮點型/字符串 列表/元組/字典/集合

文件的基本操做

打開文件的流程

# 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和3字符編碼的區別

  1. 打開python解釋器
  2. python解釋器至關於文本編輯器,讀取二進制轉化爲普通字符 a = 1
  3. 對轉化後的普通字符進行解釋(定義變量就要新開闢內存空間存放變量)
代碼詳情 Python2執行狀況 Python3執行狀況
coding:gbk
print('中')
終端:utf8
亂碼 不亂碼
coding:utf8
print('中')
終端:utf8
不亂碼 不亂碼
coding:gbk
print(u'中')
終端:utf8
不亂碼 不亂碼
coding:utf8
print(u'中')
終端:utf8
不亂碼 不亂碼

python2

用文件指定的編碼方式存儲定義後的變量

若是文件指定編碼爲'gbk' ,那就會以gbk的形式存儲變量, 原本打印的是0和1,可是終端會自動對你的0和1安裝終端默認的編碼轉換成字符 ,若是終端的默認編碼是utf8 ,亂碼; 若是終端默認編碼是gbk,不亂嗎

若是定義變量前加上u,coding:xxx不會對他形成任何影響, 由於會用unicode編碼存儲變量, 終端是任何類型的編碼均可以識別

python3

用unicode編碼方式存儲定義後的變量

之後寫文件以什麼格式存儲,就以什麼格式讀取

文件的三種打開方式

r : 只讀

f.read()

w: 清空後寫入(文件不存在自動建立)

f.write()

a: 追加(文件不存在自動建立)

f.write()

文本模式:t

二進制模式:b

t/b沒法單獨使用,只能和r/w/a一塊兒使用

with管理文件上下文

with open() as f: # 自動關閉

pyinstaller的使用

pip instlal pyinstaller

切換路徑到文件夾(文件夾包含img.ico和test.py這兩個文件)

pyinstaller -i img.ico -F test.py

文件的高級應用

文件的高級打開模式(不推薦使用)

  1. r+
  2. a+
  3. w+

文件指針的移動方法(不推薦使用)

  1. seek字節
    1. 0文件頭
    2. 1當前位置
    3. 2文件末
  2. tell字節
  3. read(n)字符
  4. truncate(n)字節, 截斷文本
    1. truncate(0) 清空文件

文件的修改

方式一

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

函數對象

  1. 引用
  2. 做爲函數的參數
  3. 做爲函數的返回值
  4. 做爲容器元素

函數的嵌套

函數內套函數

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毫無關係

總結

全局做用域內的變量和局部做用域內的變量就算變量名相同也毫無關係 ; 不一樣函數的局部做用域內的變量就算變量名相同也毫無關係

global

(全局)
x = 1

def f1():
    global x
    x = 3
  
f1()
print(x)  # 3

nonlocal

(局部)
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]

名稱空間與做用域

內置--》全局--》局部

做用域:

內置和全局 --》 全局做用域

局部 --> 局部做用域

  1. 全局做用域的(x=1)和局部做用域的(x=3)沒有關係
x = 1

def func():
    x = 3
func()

print(x)  # 1
  1. 局部做用域1(x=1) 和 局部做用域2 中的(x=3)沒有關係
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的下面的代碼
  1. 返回值(只能next獲取)
  2. 有幾個yield就只能用幾回next

return:

1.  終止函數
  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. 遞推:一層一層遞歸調用下去,進入下一層遞歸的問題規模都將會減少
  2. 回溯:遞歸必需要有一個明確的結束條件,在知足該條件開始一層一層回溯。

遞歸的精髓在於經過不斷地重複逼近一個最終的結果。

遞歸的使用方法:

參考二分法:

簡單來講就是在一列數裏邊一直從中間截斷,而後看須要的數字在那邊就保留那邊知道只剩那個須要的數。

內置函數

1.1 掌握

  1. bytes
  2. chr/ord
  3. divmod
  4. enumerate
  5. eval
  6. hash

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.2 瞭解

  1. abs
  2. all
  3. any
  4. bin/oct/hex
  5. dir
  6. frozenset
  7. gloabals/locals
  8. pow
  9. round
  10. slice
  11. sum
  12. import

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

面向過程編程

面向過程編程是解決問題的一種思想,面向過程編程,核心是編程二字,過程指的是解決問題的步驟,即先幹什麼、後幹什麼、再幹什麼、而後幹什麼……

能夠將面向過程編程想象成工廠流水線,循序漸進的運行。

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

缺點:擴展性差。

ATM+購物車

項目需求以下:

'''

  • 額度15000或自定義 ---> 註冊
  • 實現購物商城,買東西加 購物車,調用信用卡接口結帳 ---> 購物車功能,支付功能
  • 能夠提現,手續費5% ---> 提現
  • 支持多帳戶登陸 ---> 登陸
  • 支持帳戶間轉帳 ---> 轉帳
  • 記錄平常消費流水 ---> 記錄流水
  • 提供還款接口 ---> 還款
  • ATM記錄操做日誌 ---> 記錄日誌
  • 提供管理接口,包括添加帳戶、用戶額度,凍結帳戶等... ---> 管理員功能
  • 用戶認證功能 ---> 登陸認證裝飾器
    '''

用戶界面功能

1.註冊
2.登陸
3.查看額度

4.提現
5.還款
6.轉帳

7.查看流水

8.購物功能
9.查看購物車

10.註銷
q.退出

一個項目是如何從無到有:
1.需求分析:

2.程序的架構設計
    用戶視圖層:
        用戶與程序交互的.
        小的邏輯判斷

    接口層:
        業務邏輯的處理

    數據層:
        對數據進行存\取

不設計程序架構的問題:
    1.邏輯不清晰
    2.結構不清晰
    3.不便於維護

設計程序的好處:
    1.邏輯清晰
    2.結構清晰
    3.便於維護
    4.程序的解耦合

3.分任務開發
    項目經理:
        把開發任務分發給開發人員:
            提升項目開發效率
            較少項目開發週期

4.測試:
    黑盒測試:
        對用戶能看到的操做,進行測試.

    白盒測試:
        對程序的性能進行測試.

5.上線運行
    交給運維人員部署上線,運營.
相關文章
相關標籤/搜索