Python3系統學習記錄
- 1、Python簡介
- 2、安裝Python3.7
- 3、第一個Python程序
- 4、Python基礎
- 5、函數
- 6、高級特征
- 7、函數式編程
- 8、模塊
- 9、面向對象編程
- 10、面向對象高級編程
- 11、錯誤、調試和測試
- 12、IO編程
- 13、進程和線程
- 14、正則表達式
- 15、常用內建模塊
- 16、常用第三方模塊
- 17、virtuallenv
- 18、圖形界面
- 19、網絡編程
1、Python簡介
-- 代碼簡潔,運行速度慢
-- 日常任務、網站(youtobe、Instagram)、網絡游戲后臺
-- 不能寫OS、寫手機應用可以Swift/Objective-C和Java(Android)、3D游戲(C或者C++)
-- 內置庫豐富
-- 優雅、明確、簡單
-- 解釋性語言,逐行翻譯成機器碼,很慢
-- 對于網速慢的前提,比方說網絡需要等待1s,Python程序需要0.1s,而C程序只需要0.001s,其實差別不大
-- 代碼不能加密
2、安裝Python3.7
-- Python2.x和Python3.x不兼容
-- 下載exe64位安裝包:https://www.python.org/ftp/python/3.7.0/python-3.7.0-amd64.exe
-- 把python主目錄下面的Script文件夾路徑加入到Path中
-- Python解釋器很多種,使用最廣泛的是CPython
3、第一個Python程序
-- >>> print(100+200)
-- 單引號和雙引號都可以用來定義字符串
-- exit()退出Python交互模式
-- 2**10=1024
-- 文件名由英文字母、數字、下劃線組成
-- linux下面可以直接運行python文件,只需要在首行加上特殊注釋,并且給文件授執行權限
-- 輸出串可通過逗號隔開,其輸出結果用空格代替逗號
-- name=input("please enter your name")
4、Python基礎
-- 縮進語法(4個空格)
-- 數據類型:整數(0x開始表示十六進制)、浮點型(科學記數法)、字符串(單引號和雙引號,注意轉義。r''里面字符串默認不轉義)、布爾值(True、False)、None
-- ('''...''' 表示有多行)
-- 用 and、or、not 操作布爾值
-- // 整除
-- 字符編碼。Unicode把所有語言都統一到一套編碼里面,這樣不會有亂碼問題
-- ASCII 1個字節、Unicode 2個字節、UTF-8 1-6個字節可變長
-- ord('') 把單個字符轉為整數表示,chr()函數把編碼轉換為對應的字符
-- b'' 表示是bytes類型字符
-- len() 用來計算字符串長度和bytes類型的字節數
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-- 格式化輸出:print('%s,%d' % ('你好',14656)),用 %%來表示輸出中包含%,也是轉義
-- list 有序集合,隨時增刪元素,classmates=[],classmates.append('Jack'),len(classmates),classmates.insert(1,'Lucy'),classmates.pop(),classmates.pop(i),classmates[1]=Henry
-- tuple 元組,與list類似,但是一旦初始化就不可變。t=()或t=(1,)
-- if/else else if/elif。if x: 只要x是非零數值、非空字符串、非空list等就判斷為True
-- input()讀入的是str型數據,如果需要整型則需要強制轉換 age=int(sage)
-- for in循環,range()函數生成一個證書序列,通過list()函數可以轉換為list,如 list(range(1,100))
-- break、continue。不要頻繁使用這兩個語句,會造成代碼執行邏輯分叉過多
-- Ctrl+C推出程序或強制結束Python進程
-- dict 字典,鍵-值,查詢速度極快,因為添加了索引。如同在字典中查詢某個不認識的字一樣,一種是從頭到尾查,另一種是拼音或者部首查詢。占用空間大,內存浪費多。空間換時間
-- d={'name':'Henry','age':18},d['height']=168,'name' in d,pop('age')
-- set 不可重復集合,無序。s=([1,2,3]),s.add(key)
5、函數
-- abs()、max()、int()、str()、bool()、float()、hex()、sqrt()、trim()
-- def functionName():
-- from fileName import functionName 引入某類中的某方法
-- pass 空占位符
-- isinstance(5,(int,float)) 類型判斷
-- return age,name 返回多個值,其實是返回一個tuple元組
-- x,y=functionName() 接受多個值
-- 對參數類型做檢查
-- raise TypeError('Bad Type Operator')
-- 沒有return語句時,自動返回 return None
-- 默認參數一定要用不可變對象,如果是可變對象,程序運行時會有邏輯錯誤
-- 遞歸函數,使用時注意反之棧溢出。棧數據結構大小有限
6、高級特征
-- L=[],L[0:55]。切片功能,左閉右開,L[:10] 前10個,L[-10:]后10個,L[::5] 每5個取一個
-- enumerate(L),把List轉變為 索引-元素對
-- 列表生成 [x*x for x in range(1,11) if x%2==0]。[生成計算結果 數據范圍 生成篩選條件]
-- 生成全排列 [X+Y for X in 'ABC' for Y in 'abc']
-- [d for d in os.listdir('C:')] 列出C盤下全部目錄文件
-- 生成器 generator,可以在循環的過程中不斷推算出后續的元素,把list的[]改成()即可
-- (d for d in os.listdir('C:'))
-- 用 yield修飾生成器中需要返回的值,除此之外,執行流程也和函數不同。generator在每次調用next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行
-- 可以被next()函數調用并不斷返回下一個值得對象稱為迭代器:Iterator
-- Iterator可以理解為懶加載的數據類型, Iterator對象=iter(Iterable對象)
7、函數式編程
-- 高度抽象的編程范式,允許把函數本身作為參數傳入另一個函數,這種函數就稱之為高階函數,還允許返回一個函數。Python不是純函數式編程語言
-- 變量可以指向函數
-- def add(x,y,f):return f(x)+f(y)。其中f可以傳入 abs作為參數
-- map(函數1,函數1操作的每個參數的集合),如 map(abs,[-1,-4,-5,-3,-9])
-- reduce,導包 from functools import reduce。 reduce(pow,[2,3,4,5]) 等同于 pow(5,pow(4,pow(2,3))))
-- filter() 過濾元素 list(filter(is_odd,[1,2,3,6,6,7,3,4,3])),is_odd函數是用來判斷一個數是不是基數,是就返回True。屬于Iterator,惰性結構
-- sorted排序,如 sorted([1,5,7,9,3,6])。也可以 sorted([-5,-1,-9,-11,-3],key=abs) 按絕對值大小排序
-- sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True) 忽略大小寫后反向排序
-- 匿名函數 list(map(lambda x:x*x,[1,2,3,4,5,6]))
-- 裝飾器,對函數進行加強(略難)
-- 偏函數,functools.partial(int, base=2),int()函數默認是把str轉為int型,是應為base參數默認為10。
8、模塊
-- 一個 .py文件就是一個模塊,又引入包這個概念
-- .py文件中第一個字符串都被是為模塊的文檔注釋,__author__='WuDG'
-- __xxx__是特殊變量,有特殊用途, _xxx_和__xxx 的函數或變量是非公開的(private),這里是封裝和抽象
-- 安裝模塊,使用pip工具(pip install 模塊名)
9、面向對象編程
-- 繼承、封裝、多態
-- 類和實例的關系
-- 可以通過 實例對象.屬性名=屬性值 來將屬性放到這個實例對象中
-- 可以將類中的變量名加__,就可以設置為private私有變量,外部代碼就不能訪問該變量。向外部提供訪問接口,避免傳入無效的參數。其實可以通過 _類名__屬性名 來訪問
-- __變量名__ 是特殊變量,可以直接訪問
-- class Cat(Animal)
-- 對于靜態語言(如Java)來說,如果需要傳入Animal類型,則傳入的對象必須是Animal類型或者它的子類,溝澤,將無法調用run()方法。對于Python這樣的動態語言來說,則不一定要傳入Animal類型。我們只需要保證傳入的對象有一個run()方法就可以了。
-- file-like object
-- isinstance([1,2,3,4],(list,tuple))
-- dir() 獲取一個對象的所有屬性和方法
-- len(L)=L.__len__()
-- setattr(對象實例名,屬性名,屬性值) 來插入一個屬性
-- getattr(對象實例名,屬性名,<可選 屬性默認值>) 來獲取到實例對象的屬性值
-- hasattr(對象實例名,屬性名) 來判斷實例對象是否有這個屬性
-- del 實例名.屬性名 刪除實例擁有的屬性
-- 實例屬性屬于各個勢力所有,互不干擾。類屬性屬于類所有,所有實例共享一個屬性,不要對實例屬性和類屬性使用相同的名字,否則將產生難以發現的錯誤。
10、面向對象高級編程
-- 多重繼承、定制類、元類...
-- 可以給某個實例綁定一個方法。 對象名.方法名=MethodType(方法名,對象名) s.set_age=MethodType(set_age,s)。s.set_age=屬性值
-- 也可以給某個類綁定一個方法。只是將上面的實例名改成類名即可。(python交互窗口未測試成功)
-- class Student(object): __slots__ = ('name', 'age')。用__slots__變量來限制只能對實例中添加某些屬性。
-- __slots__ 變量對繼承的子類不起作用。除非在子類中也定義了__slots__ ,這樣,子類實例允許定義的屬性就是自身的__slots__加上父類的__slots__。
-- 限定屬性值的范圍和修改屬性值的手段。
-- @property 可以讓調用者寫出簡短的代碼,同時保證對參數進行必要的檢查,這樣,程序運行時就減少了出錯的可能性
-- 多重繼承(MixIn)
-- 定制類,也就是類似重寫父類的方法。如 __str__、__repr__、__call__
-- 用 callable()方法來判斷一個對象是否能被調用
--枚舉類, Month=Enum('Month',('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')),value屬性是自動賦給成員int常量,默認從1開始技術
-- Enum 可以把一組相關常量定義在一個class中,而且class不可變,同時成員可以直接比較
-- type()可以返回一個對象的類型,又可以返回一個對象的新類型。
-- 元類 metaclass,先定義metaclass,就可以創建類,最后創建實例。(不好理解)
11、錯誤、調試和測試
-- 跟蹤程序的執行,查看變量的值是否正確,這個過程成為調試。python的pdb可以讓我們以單步方式執行代碼
-- 錯誤處理機制,可以用錯誤代碼來表示出錯問題
-- try...except...finally...
-- 如果沒有錯誤發生,可以在except語句后面加一個else,當沒有錯誤發生時,會自動執行else語句
-- BaseExcepiton是所有異常的父類
-- 出錯的時候,一定要分析錯誤的調用棧信息,才能定位到錯誤的位置
-- 日志模塊 import logging, logging.方法名()
-- 拋出異常 raise 異常名()。 如 raise FooErroe(‘invalid value:%s’ % s)
-- 調試:print()、斷言、logging、pdb調試器
-- 斷言 assert n!=0,'n is zero',可以通過加入參數-O來關閉斷言,如 python -O err.py。這個assert就相當于pass語句
-- 通過簡單的配置,一條語句可以同時輸出到不同的地方,比如console和文件
-- pdb調試器,通過添加參數 -m pdb 啟動后,pdb定位到下一步要執行的代碼,輸入1來查看代碼,輸入n可以單步執行代碼。可以通過 p 變量名來查看變量,輸入命令 q 推出程序。
-- pdb.set_trace() 不需要但不執行,只需要 import pdb,然后再可能出錯的地方放一個 pdb.set_trace()就可以設置一個斷點,程序會在設置斷點的地方暫停并進入pdb調試環境,可以用命令 p 查看變量,或者用命令 c 繼續運行
-- 帶有調試功能的IDE工具。如 Visual Studio Code、Pycharm等
-- 單元測試,import unittest,可以通過添加參數 -嗎unittest來運行單元測試代碼
12、IO編程
-- 同步IO/異步IO,區別在于CPU是否等待IO操作
-- 用with來解決文件打開關閉問題 with open('/path/to/file', 'r') as f:print(f.read())
-- 讀文件 f = open('2019-7-3 工作日志.txt', 'r')。r是讀取 UTF-8編碼的文本, rb是讀取圖片、視頻等二進制文件,若要讀取非UTF-8編碼的文本,則需要添加一個參數指定編碼方式,如encoding=gbk,讀取文本文件過程中可能遇到編碼錯誤,可以添加一個參數 error='ignore'來忽略錯誤
-- 寫文件 w和wb代替r和rb即可
-- 在內存中讀寫數據, from io import StringIO f=StringIO() f.write('hello world') print(f.getvalue())
-- 初始化一個 StringIO。 f=StringIO('i am a student,\n and you?\n you are a work!!!') f.readline()
-- ByteIO操作二進制數據。f=BytesIO("你好呀".encode('utf-8'))
-- os模塊。import os os.environ os.name os.rename('原','目標') os.remove('文件名')
-- os.path.abspath('.') 獲取當前目錄絕對路徑。os.mkdir('D:\\dev\\testDir') os.rmdir('D:\\dev\\testDir')
-- 列出當前目錄下全部文件夾 [x for x in os.listdir('.') if os.path.isdir(x)]
-- 列出當前目錄下全部.py文件 [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
-- 復制文件 import shutil 。shutil.copyfile('test.txt','copytest.txt')
-- 序列化 把變量從內存中變成可存儲或傳輸的過程稱之為序列化,在python中交pickling。序列化之后,就可以把序列化后的內容寫入到磁盤或者通過網絡傳輸到別的機器上
-- 序列化到二進制文本中 import pickle d=dict(name='henry',age=18,job='work') pickle.dumps(d) f=open('birany.txt','wb') pickle.dump(d,f) f.close()
-- 反序列化 f=open('birany.txt','rb') r=pickle.load(f) f.close() r {'name': 'henry', 'age': 18, 'job': 'work'}
-- json將python對象序列化為字符串。import json json.dumps(d) json.loads(json_str)
-- 把任意對于序列化成json:json.dumps(s, default=lambda obj: obj.__dict__)
13、進程和線程
-- 進程與線程之間的關系
-- 線程是最小的執行單元,而進程由至少一個線程組成,完全由操作兄決定,程序自己不能決定什么時候執行和執行多久。多進程和多線程的程序涉及到同步、數據共享等問題,編寫起來更復雜。
-- 多進程 linux系統下提供os.fork(),Windows下提供了跨平臺版本的多進程multiprocessing模塊
-- 通過進程池的方式批量創建子進程
-- 通過subprocess調用系統命令,如r = subprocess.call(['nslookup', 'www.python.org']),這和直接輸入命令 nslookup www.python.org 作用相同
-- 進程間通信是通過 Queue和Pipes。
-- Python 解釋器由于設計時有GIL全局所,導致了多線程無法利用多核,多線程的并發在Python中即使一個美麗的噩夢
-- ThreadLocal變量雖然是全局變量,但每個線程都只能讀寫自己線程的獨立副本,互不干擾。ThreadLocal解決了參數在一個線程中各個哈書之間互相傳遞的問題。
-- 線程切換時間開銷問題。計算密集型 VS IO密集型。計算密集型任務同時進行的數量應當等于CPU核心數
-- 分布式進程
14、正則表達式
-- \d 一個數字、\w 一個字母或者數字、 . 任意一個字符、 * 任意個字符、 + 至少一個字符、 {n} 表示n個字符、? 表示0個或1個字符、{n,m} 表示n到m個字符
-- [0-9a-zA-Z\_]+ 至少一個由數字、字母、下劃線組成的字符串
-- [a-zA-Z\_][0-9a-zA-Z\_]* 匹配Python合法變量
-- A|B A或B (P|p)ython 匹配 python或Python
-- ^ 表示行的開頭,如 ^\d表示必須以數字開頭
-- $ 表示行的結尾,如 \d$ 表示必須以數字結尾
-- import re re.match(r'^\d{3}\-\d{3,8}$', '010-12345')
-- 切分字符串 re.split(r'[\s\,]+', 'a,b, c d')
-- 分組 通過()來實現 m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
-- m.group(0) '010-12345' m.group(1) '010' m.group(2) '12345'
-- 貪婪匹配,正則匹配默認是貪婪匹配,也就是匹配盡可能多的字符。
-- 編譯,如果一個正則表達式要重復使用很多次,處于效率的考慮,可以進行預編譯該正則表達式。re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$') 然后直接使用 re_telephone.match('010-12345').groups() 即可
15、常用內建模塊
-- datetime from datetime import datetime datatime.now()
-- 構造時間和時間戳 print(datetime(2019,7,5,15,50).timestamp())
-- 時區不同 datetime.utcfromtimestamp(datetime(2019,7,5,15,50).timestamp())和datetime.fromtimestamp(datetime(2019,7,5,15,50).timestamp()) 這是本地時間
-- 時間字符串格式化成 datetime對象 datetime.strptime('2015-6-1 18:19:59', '%Y-%m-%d %H:%M:%S')
-- datetime對象轉換為世界字符串:datetime.now().strftime('%a, %b %d %H:%M')
-- datetime 加減,導入 timedelta模塊。print(datetime.strptime('2015-6-1 18:19:59', '%Y-%m-%d %H:%M:%S')+timedelta(hours=10))
2015-06-02 04:19:59
-- datetime 標識的時間需要時區信息才能確定一個特定的時間,否則只能視為本地時間。如果要從年初datetime,最佳方法是將其轉換成timestamp再存儲,因為timestamp的值與時區無關
-- namedtuple namedtuple('名稱', [屬性list]) Point = namedtuple('Point', ['x', 'y'])或者Circle = namedtuple('Circle', ['x', 'y', 'r'])
-- deque 雙向列表 q = deque(['a', 'b', 'c']) q.append('x') q.appendleft('y')
-- deque 除了實現了list的append方法和pop方法之外,還支持appendleft和popleft等方法,這樣就可以非常高效地往頭部添加或刪除元素
-- defalutdict 提供了key不存在時返回一個默認值,而不是報錯。
-- OrderDict 保持鍵值插入的順序
-- Counter 計數器,可以用來統計字符出現個數
-- Base64 是一種任意二進制到文本字符串的編碼方法,常用語URL、Cookie、網頁中傳輸少量二進制數據
-- struct 模塊中pack函數把任意數據類型變成bytes
-- hashlib 摘要算法(md5、SHA1),也稱哈希算法、散列算法,它通過一個函數,把任意長度的數據轉換為一個長度固定的數據串(通常用16進制的字符串表示)。目的是為了發現原始數據是否被人篡改過
-- 摘要算法應用 密碼存儲。加鹽。摘要算法不是加密算法,不能用于加密(因為無法通過摘要反推明文),只能用于防篡改,但是它的單向計算特特性決定了可以在不存儲明文口令的情況下驗證用于口令
-- Hmac算法,在計算哈希的過程中,把key混入計算過程。hmac.new(key,message,digestmod='MD5') key和message都是bytes類型 。
-- itertools提供了非常有用的用于操作迭代對象的函數。itertools.count(1)會產生一個自然數迭代對象、itertools.cycle(字符串1) 會產生字符串1的循環迭代、repeat('第一個元素','次數')把一個元素無限重復下去,
-- takewhile()函數根據條件判斷來截取出一個有限序列、chain()函數可以把一組迭代對象串聯起來,形成一個更大的迭代器 for c in itertools.chain('ABC', 'XYZ')
-- groupby()把迭代器中相鄰的重復元素挑出來放一起 for key, group in itertools.groupby('AAABBBCCAAA'):
-- itertools模塊提供的全部是處理迭代功能的函數,他們的返回值不是list,而是Iterator,只有for 循環迭代的時候才真正計算
-- 并不是只有open函數返回的fp對象才能使用with語句。只要正確實現了上下文管理,就可以用于with語句。實現上下文管理是通過 __enter__和__exit__這兩個方法實現的
-- @contextmanager也可以實現對上下文的管理功能,如 計算一個函數的運行時間
-- urllib 提供了一系列用于操作URL的功能
-- xml解析 。DOM vs SAX,DOM會把整個xml讀入內存,解析為樹,慢但是可以任意遍歷樹的節點。SAX 流模式,邊讀邊解析,內存小,快
-- html解析
16、常用第三方模塊
-- 所有的第三方模塊都會在 https://pypi.org/ 上面注冊,只需要找到對應的模塊名字,就可以直接用 pip工具進行安裝操作
-- pillow 強大的圖片處理標準庫。修改圖片尺寸、圖片模糊、生成驗證碼
-- requests, urllib模塊可以用于訪問呢網絡資源,但是用起來麻煩,而且缺少很多實用的高級功能,而requests處理URL資源特別方便
-- 檢測編碼模塊 chardet。chardet.detect(b'Hello, world!') 支持檢測中文、日文、韓文等
-- (3.4安裝失敗)psutil 系統監控模塊。 psutil.cpu_count() # CPU邏輯數量 psutil.cpu_count(logical=False) # CPU物理核心 psutil.cpu_times() psutil.disk_partitions() # 磁盤分區信息
17、virtuallenv
-- python環境隔離模塊。由于不同的項目需要的環境和模塊不同,所以引入這個模塊的作用很大
18、圖形界面
-- Tk(python自帶,無需安裝)、wxWidgets、Qt、GTK
-- Tkinter可以滿足基本的GUI程序要求,如果是非常復雜的GUI程序,建議用操作系統原聲支持的語言和庫來編寫
-- 海龜繪圖
19、網絡編程
-- TCP/IP簡介 為了把全世界所有不同類型的計算機都鏈接起來,規定的一套全球通用的協議,TCP和IP協議最為重要,所以把互聯網的協議簡稱TCP/IP協議
-- TCP編程 服務器綁定UDP端口和TCP端口互不沖突
未完待續…
原文路徑:
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
