菜鳥筆記 Python (一)

Python是“龜叔”在1989年打發無聊聖誕節的創作

我無聊時候在幹嘛? 發呆

1.前言

  1. 缺點

    1. 運行速度慢 解釋性,翻譯成CPU能理解的機器碼
    2. 代碼不能加密 發佈程序就是發佈原碼,編譯型就是機器碼發佈,
  2. 版本

    1. 2.x和3.x不兼容
  3. 命令行執行

    1. python hello.py
  4. 輸出

    1. print("hello","world")中間的逗號表示輸出一個空格
  5. 輸入

    1. input() 返回的是字符串類型

前言就到這裏啦! 最最基本的東西,py本身入門也是很簡單的,有編程基礎的很快就可以入門

2.基礎

  1. 註釋
    1. # 可不是什麼雙斜槓哦 ,雙斜槓在其他地方另有含義
  2. 縮進
    1. 堅持四個空格
    2. 縮進使 複製-粘貼變得麻煩
  3. 數據類型
    1. 整數 任意大小,永遠是精確的
    2. 浮點數 存在四捨五入
    3. 字符串
      1. 轉義字符前面加上反斜槓取消轉義
      2. 單引號,雙引號普通字符,存在轉義
      3. 三引號原樣輸出,不存在轉義
      4. 表示
        1. 在內存中是 Unicode
        2. 把字符送到網絡或磁盤上需要編碼成byte encode name=b"Primer" 注意前綴b
        3. 從網絡或磁盤上讀取字符需要解碼 decode
      5. 格式化輸出 (C語言的都理解)
        1. 方法一 %
          1. %d
          2. %f
          3. %s
          4. %x
          5. 但是用法有點特別 print("hello,%s"%("primer")) 注意百分號和括號裏面的內容
        2. 方法二 format()
          1. print("hello,{0},今晚去哪? 去{1}".format("小李","派對"))
    4. 布爾值
      1. 只有 True False
      2. 結合 and or not
    5. 空值
      1. None
  4. 編碼
    1. 可變長編碼 UTF-8 又一個Unicode字符,根據字符所用字節個數,編碼成二進制大小
    2. 獲取字符的十進制數 ord(char) 只接受單個字符
    3. 根據十進制數獲取字符 chr(int)
    4. 編碼轉換 string.encode(編碼格式)
      1. 注意編碼範圍,比如中文不能使用ascii轉換,中文的範圍大,由輸出單個字符的十進制數大小可知
  5. list
    1. 定義是使用中括號
    2. 與C語言的數組無差別,有一點特殊的就是可以反向負數遍歷 -1表示最後一個,以此類推
  6. tuple
    1. 不可修改
    2. 定義是使用小括號
    3. 只有一個元素時候需要末尾加逗號
  7. 條件判斷
    1. if True:
    2. else :
    3. elif True :
  8. 循環
    1. for item in items:
      1. range(number) 生成0-number-1的整數序列
    2. while True :
      1. break ,continue
  9. 字典 dict
    1. Java中的map
    2. d={'name':'primer'}
    3. key不可變
  10. set
    1. 值不重複
    2. s = set([1,2,3]) 需要提供一個list

3.函數

  1. def 定義函數

    def hello(x):
    
  2. 空函數 def nop(): pass

    1. pass就是個佔位符是代碼正常運行,再無它意,但缺少就是語法錯誤
  3. 多返回值 return 23,456

    1. 假象的多返回值,其實就是返回一個不可變的tuple,go語言的纔是真的多值返回
  4. 默認參數

    1. 一定要指定不變對象 def addstr(name=None):
  5. 可變參數

    1. def fun(*num) 星號的使用 其實就是參數被封裝爲tuple傳到裏面去
  6. 關鍵參數 注意咯,一個參數就是一個字典類型

    def funb(**b):
        print(b)
    
    funb(city="japan",name="primer")
    

4.高級特性

  1. 切片
    1. 操作對象 list tuple
    2. a[0:3] 0省略
    3. a[-2:-1] 倒數
    4. "主函數"[:2]
  2. 迭代
    1. for i in items 只要items是可迭代的對象 [如何判斷對象是否可迭代? isinstance(obj,iterable)]
    2. 下標迭代 for i, value in enumerate(['A', 'B', 'C']):
  3. 列表生成式
    1. 生成一個列表list ? 什麼樣的列表,你儘管想!
  4. 生成器 generator
    1. 一邊循環一邊計算,不一次性生成全部數據
    2. (x * x for x in range(10))
    3. 獲取下一個元素 next(g) 調用next時候就是在計算下一個元素的值並獲取

5.函數式編程

  1. 特色

    1. 允許把函數本身作爲參數傳給函數,允許返回函數
  2. 高階函數

    1. 函數名也是變量,可以把函數名賦值給變量,那麼該變量就相當於是此函數的別名
      1. map/reduce
      2. map接受一個自定義函數和序列
    2. filter 過濾
      1. 過濾函數,滿足條件就留下元素,否則刪除
      2. 惰性函數,需要的時候纔會執行過濾 怎麼理解惰性? 比如已件事情,能留給明天做的絕不今天做(可我不想),能有多懶就多懶,能拖多久就拖多久
    3. sorted
      1. sorted([],key)
  3. 返回函數

    1. 把函數作爲返回結果 這種返回其實是惰性的,你若是需要結果,則把返回的值作爲函數形式再執行一次即可[就是變量後面在家一對小括號表示執行該函數]
    2. 閉包
  4. 匿名函數

    1. lambda x: 函數體
  5. 裝飾器

    1. 函數名就是變量,可以再次複製,然後調用就是 f() 加小括號形式

    2. 屬性__name__ 獲取函數屬性,比如函數名__main__就是函數入口

      if __name__ == '__main__':
          print(__name__) #輸出__main_
      
    3. 所以什麼是裝飾器? Java中的裝飾模式一樣,就是:運行期間動態添加功能

      1. 本質是返回函數的高階函數 一開始有點懵,慢慢理解
      2. decorator裝飾器就是接受一個參數是函數的函數? 有點繞了? 比如:以前函數的參數是int,那麼作爲裝飾器時候,函數的參數就是 函數 ok?
  6. 偏函數

    1. functools.partial 創建偏函數
    2. 啥事偏函數?還沒理解?
      1. 把一個函數的某些參數給固定住(也就是設置默認值),返回一個新的函數

6.模塊

  1. __init__.py文件
    1. 每一個包目錄下面都會有一個,這個文件是必須存在的,否則,Python就把這個目錄當成普通目錄,而不是一個包
  2. 調用另一個包中__init__.py中的函數
    1. 先導入包 import primer
    2. 調用函數需要加包名 primer.sayName("tom")
  3. 調用另一個包中其他 py文件的函數
    1. 導入該py文件 from primer import Hello
    2. 調用函數需要加py文件名 Hell.Who("tom")
  4. 作用域 Java中的public等
    1. 下劃線_開頭的變量時 private私有的
  5. 安裝第三方包
    1. 方式一
      1. 工具pip 我在安裝PyCharm時候勾選安裝並且添加到path環境變量中了
      2. 安裝 pip install name
    2. 方式二
      1. Anaconda工具
      2. 導包import name

7.面向對象

  1. 抽象的模板

    class Student(object): 
      pass
    
    #objetc表示繼承自哪一個父類,object就是終極父類,與Java中的Object是一樣的
    
  2. 在類裏面訪問控制符就起很大作用了,就是下劃線開頭的變量或者方法名

  3. __init__方法 兩個下劃線哦,我認爲跟構造函數類似

class Student():

    def __init__(self,name,id):
        self.name = name
        self.id = id

    def sayName(self):
        print(self.name)

if __name__ == '__main__':
    print("程序入口")
    s = Student("老李",24)
    s.sayName()
    
    
# self代表本身,第一個參數永遠是self,其餘跟普通函數一致    
  1. 特殊變量 __name__

    1. 雙下劃線開始,雙下劃線結束
    2. 可以直接訪問
  2. 訪問權限

    1. 雙下劃線開頭 __init__ private 不可以訪問
    2. 單下劃線開頭 _name protected 可以訪問,但不建議訪問
    3. 其餘合法字符 id 公開訪問
  3. 繼承 支持多繼承

    class Man():
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def person(self):
            print("我是人")
    
    class Student(Man):
    
        def __init__(self,name,age,clazz):
            self.clazz =clazz
            self.name=name
            self.age=age
    
        def whoIam(self):
            print(self.name)
            print(self.age)
            print(self.clazz)
    
    if __name__ == '__main__':
        print("程序入口")
        s = Student("老李",24,"假網工")
        s.whoIam()
        s.person()
    
  4. 獲取對象信息

    1. 判斷對象類型
      1. type(obj) 返回類型
      2. isinstance(obj,str) 指定變量是否是給出的類型
    2. 獲取對象的所有屬性和方法 dir(str)

8.面向對象高級編程

  1. __slots__

    1. 目的? 動態給類添加屬性或者方法. 在Java動態語言中是很容易的,就是類似調用setName("kg");
    2. 在python中呢?
      1. __slots__ = ('qq','telNumber') 就相當於是類中存在兩個變量 qq telNumber [我思考也實踐了一個問題就是:我若是qq加雙下劃線會不會是private不可訪問的? 顯然結果不是.我想的是,既然__slots__明確說目的是爲了動態添加值,再私有化就沒有意義了.]
  2. @property

    1. 保護數據不易被修改
    2. 這個註解就是個裝飾器 不記得裝飾器是啥了? 聯想動態添加功能啊,裝飾模式
  3. 多繼承

    1. class Student(Person,Man): pass
    2. Minln 就是像Java那種繼承一個類,實現多個接口類似,這是一種設計
  4. 定製類

    1. __str__ 不就是類似toString方法嘛 [兩者的區別是__str__()返回用戶看到的字符串,而__repr__()返回程序開發者看到的字符串,也就是說,__repr__()是爲調試服務的。]
    2. __iter__ 返回迭代對象
  5. 枚舉類

    1. Moth=Enum('one','tow')
    2. class Moth(Enum)
  6. 元類

    1. type()

      1. 判斷類型 type(name)

      2. 創建類 Hello = type('Hello', (object,), dict(hello=fn)) # 創建Hello class

        1.class的名稱;
        2.繼承的父類集合,注意Python支持多重繼承,如果只有一個父類,別忘了tuple的單元素寫法;
        3.class的方法名稱與函數綁定,這裏我們把函數fn綁定到方法名hello上
        

        看着優先香Java的反射[我瞎想的]

    2. metaclass [聽說是很難的魔法棒,可以實現ROM框架,聽聽就刺激,先跳過,老子也是菜鳥,暫看不懂]

9.錯誤處理

  1. 錯誤處理

    1. try .. except .. finally..
  2. 調試

    1. print() 自己俗稱的中間變量輸出
    2. 斷言 assert true, error message
    3. logging內置日誌,輸出到文件 日誌一般都會有日誌級別
    4. pdb 單步執行
    5. 好好利用IDE的功能
  3. 單元測試

    1. 導入測試模塊 unittest

    2. 編寫測試類,繼承導入的模塊 class TestAdd(unittest.TestCase): pass

    3. 然後理由self不斷測試自身

    4. 運行測試類

      if __name__ == '__main__':
          unittest.main()
      
    5. setUp()tearDown()方法。這兩個方法會分別在每調用一個測試方法的前後分別被執行。

  4. 文檔測試

    1. 執行寫在註釋中的代碼? 什麼? 震驚菜鳥,我也是第一次聽說,怪我太菜 /掉頭流淚狂奔
    2. 使用doctest來測試

10. IO編程

  1. 文件讀取

    1. open(path,mode) 打開文件

    2. read() 一次讀完內容

    3. close()

    4. readlines()每次讀取一行

    5. 自動關閉文件

      with open('/path/to/file', 'r') as f:
          print(f.read())
      
    6. open(path,'rb')讀取二進制文件

    7. open(path,mode,encoding='gbk')字符編碼

  2. 寫文件

    1. open(path,'w')
    2. write(str)
    3. 也可以使用上述的with自動關閉
  3. String IO / Bytes IO

    1. 在內存中讀寫

      f=StringIO()
      #寫
      f.write(str)
      #讀
      f.getvalue()
      
    2. 區別就是 StringIO操作字符串 Bytes IO操作字節

  4. 序列化

    1. pickle模塊
    2. pickle.dumps(obj)序列化任意對象爲字節流
    3. pickle.load(obj)反序列化
    4. josn序列化,調用的方法名一致,結果不一樣

11.進程和線程

  1. 多進程
    1. os模塊中 fork()調用,子進程返回0,父進程返回子進程ID
    2. fork()只能在Linux上面使用,故Windows不行,mac也是基於Linux/Unix
    3. 所以在Windows上怎麼使用多線程?
      1. p = Process(target=fun,args=('primer',))
      2. 這句話有些坑啊
        1. target接受的是函數名而不是函數調用
        2. args接受的是tuple
        3. 當tuple只有一個元素的時候,末尾需要加逗0號,
      3. p.start() p.join() 線程開始和等待
    4. Pool線程池 創建大量子線程時候使用
    5. p = Pool(4) p.apply_async(target,args)
    6. Pool默認大小是CPU核數,當出現線程數大於CPU核數的時候,就會出現競爭的現象
    7. 子進程 subprocess
  2. 多線程
    1. _thread是低級模塊,threading是高級模塊
    2. Python解釋器由於設計時有GIL全局鎖,導致了多線程無法利用多核。多線程的併發在Python中就是一個美麗的夢
  3. 本地線程
    1. 使用自己的局部變量,避免過多使用全局變量,對全局變量加鎖使代碼臃腫
  4. 分佈式進程
    1. Process可以分佈到多臺機器上,而Thread最多隻能分佈到同一臺機器的多個CPU上。

12.常用內建模塊

  1. datetime 時間處理
    1. datetime.now()當前時間
    2. datetime.now().timestamp()轉換成時間戳
    3. datetime.fromtimestamp(time)把時間戳轉換
  2. collections 集合
  3. namedtuple自定義tuple
  4. deque隊列
  5. defaultdict dictkey不存在的時候拋出異常,而這個不會
  6. ordereddict 有序的key,dict是無需的
  7. chainmap 串聯dict
  8. counter 計數器 返回還是一個tupel
  9. base64 使用64個字符表示二進制
    1. base64.b64encode(str) 編碼
    2. base64.b64decode(str) 解碼
    3. 注意
      1. str是字節流,需要使用b作爲前綴
      2. 不能直接轉換中文
  10. struct
    1. 處理字節數據類型
  11. hashlib
    1. 把任意數據轉換成固定長度的字符串,十六進制表示
    2. 常見的MD5 sha1
  12. hmac
    1. 驗證數據的有效性 token對比
  13. iteratools
    1. 遍歷工具
  14. contextlib
    1.
  15. urllib
  16. xml
  17. htmlparser

13.網絡編程

  1. tcp
    1. 可靠
    2. socket使用
    3. 一句話總結,比之前自己使用c++寫的做了很多封裝,只暴露幾個方法
  2. udp
    1. 不可靠
    2. 無連接
    3. 直接調用sendto

14.數據庫

  1. sqlinte 這不是Android中使用的,巧了

  2. mysql

    1. 驅動 pip install mysql-connector
  3. SQL alchemy 二維表

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章