Python基礎知識筆記

=================Python基礎知識相關筆記=====================python

  1. / 表示浮點數除法,//表示整數除法,返回不大於結果的一個最大的整數。
  2. 操做系統的做用:
    1. 把硬件醜陋負責的接口隱藏起來,爲應用程序提供良好接口
    2. 管理,調用進程,而且把進程之間對硬件的競爭變得有序化
  3. linux下的
  4. 多道技術:
    1. 產生背景:爲了實現單CPU下的併發效果
    2. 分爲兩部分:
      1. 空間上的複用(必須實現硬件層面的隔離)
      2. 時間上的複用(複用CPU時間片)
        1. 何時切換?
          1. 正在執行的任務遇到阻塞
          2. 正在執行的任務運行時間過長
  5. 進程介紹
    1. 正在進行的一個過程或者說一個任務。而負責執行任務的則是cpu。
    2. 進程與程序的區別:
      1. 程序僅僅只是一堆代碼而已,而進程指的是程序運行的過程。
      2. 同一個程序執行兩次,那也是兩個進程。 好比打開暴風影音。雖然是同一個軟件,一個播放的是蒼空井,一個播放的是飯島愛。
    3. 併發與並行:
      1. 不管是並行仍是併發,在用戶看來都是同時運行的,不論是進程仍是線程,都只是一個任務而已,真正幹活的是cpu,cpu來作這些任務,而一個cpu同一時刻只能執行一個任務
      2. 並行:真正的同時運行,只是具有多個cpu才能實現並行
      3. 併發:僞並行,即看起來是同時運行。單個cpu+多道基數就能夠實現併發(並行也屬於併發)
    4. 同步與異步:
      1. 同步就是指一個進程在執行某個請求的時候,若該請求須要一段時間才能返回信息,那麼這個進程將會一直等待下去,知道收到返回消息才繼續執行下去。
      2. 異步是指進行不須要一直等下去,而是繼續執行下面的操做無論其餘進程的狀態。當有消息返回時系統會通知進程進行處理,這樣能夠提升執行的效率。
      3. 舉個例子:打電話就是同步通訊,發短信就是異步通訊。
    5.  系統的調用:
      1. linux:fork
      2. win:CreateProgress
    6. linux下的進程與windows下的區別:
      1. linux的進程有父子關係,是一種樹形結構,windows沒有這種關係
      2. linux建立新的進程須要copy 父進程的地址空間,wind下從最開始建立進程,兩個進程之間就是不同。
  6. 線程介紹:
    1. 在傳統操做系統中,每一個進程都有一個地址空間,並且默認就有一個控制線程。
    2. 進程只是用來把資源集中到一塊兒(進程只是一個資源單位,或者說資源集合),而線程纔是CPU上的執行單位。eg: 北京地鐵是一個進程,地鐵裏的13號線是一個線程。
    3. 多線程指的是:在一個進程哩開啓多個線程,簡單的講:若是多個任務公用一塊地址空間,那麼必須在一個進程內開啓多個線程。
    4. 爲什麼要用多線程:
      1. 多線程共享一個進程的地址空間
      2. 線程比進程更輕量級,線程比進程更容易撤銷,在許多操做系統中,建立一個線程比建立一個進程要快10~100倍,在有大量線程須要動態和快速修改時,這一特性頗有用
      3. 對於計算/CPU密集型的應用,多線程並不能提高性能,但對於I/O密集型應用,使用多線程會明顯的提高速度(I/O密集型根本用不上多核優點)
      4. 在多CPU系統中,爲了最大限度的利用多核,能夠開啓多個線程(比開進程開銷要小的多)
  7. 異常處理
    1. 何時用異常處理 
      1. try...except 應該儘可能少用,由於它自己就是你附加給你程序的一種異常處理的邏輯,與你的主要工做是沒有關係的,這種東西加的多了,會致使你的代碼可讀性變差。只有在有些異常沒法預知的狀況下,才應該加上 try...except ,其餘的邏輯錯誤應該儘可能修正
  8. Socket
    1. 服務端
      import socket

      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET: internet網絡;SOCK_STREAM: TCP 流式協議
      phone.bind(('127.0.0.1', 8081)) # 至關於插電話卡
      phone.listen(5) # 至關於開機
      print('starting')

      while True: # accept 鏈接循環

      conn, address = phone.accept() # 至關於接聽電話
      print('client is coming ', address)

      while True: # 與conn的通信循環
      try: # 針對windows下,當client斷掉以後,會拋異常,須要加一個try except
      client_message = conn.recv(1024) # 讀取客服端發過來的消息,收消息
      if not client_message: break # 在linux機器上,不會識別到client斷掉的消息,會不斷的收空消息。此時須要加一個判斷。
      conn.send(client_message.upper()) # 回消息
      except Exception: # 捕捉通信終端異常
      break
      conn.close() # 掛電話

      phone.close() # 關機
    2. 客戶端 
      import socket

      phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
      phone.connect(('127.0.0.1', 8083)) # 鏈接服務器的地址

      while True:
      msg = input('>>>:').strip()
      if not msg: continue # 防止客戶端發空,當是空消息時,繼續輸入
      phone.send(msg.encode('utf-8')) # 不能直接發字符串,須要發二進制的形式的文件
      back_message = phone.recv(1024) # 接受返回的消息
      print(back_message.decode('utf-8'))

      phone.close()
    3. 經過 socket 實現 遠程執行命令:ls,pwd等
      1. 服務端
        mport socket
        import subprocess

        phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET: internet網絡;SOCK_STREAM: TCP 流式協議
        phone.bind(('127.0.0.1', 8082))
        phone.listen(5)
        print('starting')

        while True:

        conn, address = phone.accept()
        print('client is coming ', address)

        while True:
        try:
        cmd = conn.recv(1024)
        print('receive')
        if not cmd: break
        res = subprocess.Popen(cmd.decode('utf-8'),shell=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
        err = res.stderr.read()
        if err:
        cmd_res = err
        print('error')
        else:
        cmd_res = res.stdout.read()
        print('wokao cmd_res', cmd_res)
        conn.send(cmd_res)

        except Exception:
        break
        conn.close()

        phone.close()
      2. 客戶端
        import socket

        phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        phone.connect(('127.0.0.1', 8082)) # 鏈接服務器的地址

        while True:
        cmd = input('>>>:').strip()
        if not cmd: continue # 防止客戶端發空,當是空消息時,繼續輸入
        phone.send(cmd.encode('utf-8')) # 不能直接發字符串,須要發二進制的形式的文件
        cmd_res = phone.recv(1024) # 接受返回的消息
        print(cmd_res.decode('utf-8'))
        phone.close()
      3. 自定義表頭解決粘包的問題。
        1. 只有TCP有粘包,UDP則沒有粘包現象。所謂粘包問題主要仍是由於接收方不知道消息之間的界限,不知道一次性提取多少字節的數據所形成的。
        2. 服務端:
          import socket
          import subprocess
          import struct
          import json

          phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # AF_INET: internet網絡;SOCK_STREAM: TCP 流式協議
          phone.bind(('127.0.0.1', 8082))
          phone.listen(5)
          print('starting')

          while True:

          conn, address = phone.accept()
          print('client is coming ', address)

          while True:
          try:
          cmd = conn.recv(1024)
          print('receive')
          if not cmd: break
          res = subprocess.Popen(cmd.decode('utf-8'),shell=True,
          stdout=subprocess.PIPE,
          stderr=subprocess.PIPE)
          err = res.stderr.read()
          if err:
          cmd_res = err
          print('error')
          else:
          cmd_res = res.stdout.read()
          print('wokao cmd_res', cmd_res)
          # conn.send(struct.pack('i', len(cmd_res))) # 先發報頭,報頭 i 格式,會生成 int 類型的4個字節的報頭
          head_dic = {'filename': None, 'hash': None, 'total_size': len(cmd_res)}
          head_json = json.dumps(head_dic)
          head_bytes = head_json.encode('utf-8')
          conn.send(struct.pack('i', len(head_bytes))) # 先發送報頭的長度
          conn.send(head_bytes) # 再發送報頭的bytes
          conn.send(cmd_res) # 最後發送真實是數據
          except Exception:
          break
          conn.close()

          phone.close()
        3. 客戶端
          import socket
          import struct
          import json

          phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          phone.connect(('127.0.0.1', 8082)) # 鏈接服務器的地址

          while True:
          cmd = input('>>>:').strip()
          if not cmd: continue # 防止客戶端發空,當是空消息時,繼續輸入
          phone.send(cmd.encode('utf-8')) # 不能直接發字符串,須要發二進制的形式的文件

          # 先收報頭的長度
          head_struct = phone.recv(4)
          head_len = struct.unpack('i', head_struct)[0]

          # 再收報頭的bytes
          head_bytes = phone.recv(head_len)
          head_json = head_bytes.decode('utf-8')
          head_dic = json.loads(head_json)
          print(head_dic)

          # 最後根據報頭裏面的詳細信息讀取真實數據
          total_size = head_dic['total_size']

          receive_size = 0
          data = b''
          while receive_size < total_size:
          receive_data = phone.recv(1024)
          data += receive_data
          receive_size += len(receive_data)
          print(data.decode('utf-8'))

          phone.close()
  9. metaclass 元類
  10. 反射
    1. 定義: 經過字符串的形式操做對象相關的屬性。python中的一切事物都是對象(均可以使用反射)
    2. 四個方法,適用於類和對象
      1. hasattr(object,name)        # 判斷obj下是否有 name 方法
      2. getattr(object,name, defatult=None)   # getattr(p,'x','not exist')  判斷p下面是否有x方法,若是沒有則返回‘not exist’
        import ftpclient

        f1 = ftpclient.FtpClient('192.168.1.150')

        if hasattr(f1, 'get'): # 經過反射來判斷 f1 中是否有get方法,若是有該方法則執行該方法
        func = getattr(f1, 'get') # 獲得 f1 的 get方法,而後執行它
        func()
        else:
        print('沒有該方法,執行其餘操做')
      3. setattr(obj,name,value)      #setattr(p,'x', 12123232423)   # 給 obj 下的name  賦值
      4. delattr(x,y)    # delattr(Chinese,'country')      # 刪除 Chinese 下的 country 屬性
    3. class Ftpclient:

      def __init__(self,host):
      self.host = host
      print('ready to connecting')

      def run(self):
      while True:
      inp = input('---->請輸入命令').strip()
      inp_l = inp.split()
      if hasattr(self, inp_l[0]):
      func = getattr(self, inp_l[0])
      func(inp_l)
      else:
      print('沒有該命令')
      def get(self, arg):
      print('downloading file ', arg[1])

      def ls(self, arg):
      print('list the file', arg)

      f = Ftpclient('192.168.1.1')
      f.run()
  11. 模塊:
    1. 定義:一個模塊就是一個包含了python定義和聲明的文件,文件名就是模塊名字加上.py的後綴。
    2. import
    3. 倒入模塊乾的事情:eg: import spam
      1. 產生新的名稱空間
      2. 以新建的名稱空間爲全局名稱空間,執行文件的代碼執行文件的代碼
      3. 拿到一個模塊名spam,指向spam.py產生的名稱空間。
      from ... import ....    from spam import money,read1
      1. 產生新的名稱空間
      2. 以新建的名稱空間爲全局名稱空間,執行文件的代碼執行文件的代碼
      3. 直接拿到的就是 spam.py 產生的名稱空間中的名字。
      4. 優勢:方便,不用加前綴。缺點:容易跟當前文件的名稱空間衝突
      5. from xxx improt *  // 導入全部。
        1. __all__=[a,b,c]  //__all__ 用來控制 import * 來導入什麼。
    4. import模塊以後,模塊的查找搜索路徑:
      1. 先在內存中查找,再查找內置函數,最後再 sys.path 路徑 
      2. 若是本身寫的模塊,沒法import的時候,就須要操做 sys.path 路徑
        1. import sys
        2. sys.path.appen('路徑')  若是想優先級高: sys.path.insert(0,'路徑')
        3. 這樣就能夠 import了。
  12. 包:
    1.  定義:包是一種經過使用:".模塊名" 來組織python模塊名稱空間的方式。
      1. 不管是import形式仍是 from...import形式,凡是在導入語句中(而不是在使用時)遇到帶點的,都要第一時間提升警覺:這是關於包纔有的導入語法
      2. 包是目錄級別的(文件夾級),文件夾是用來組成py文件(包的本質就是一個包含__init__.py文件的目錄)
  13. __name__控制python文件在不一樣用途下的行爲:
    1. 當 XXX.py 看成腳本執行時,__name__ = ‘__main__’
    2. 當 XXX.py 看成模塊導出時,__name__ = 模塊名(XXX)
  14. 遞歸函數與二分法:
    1. 定義:在調用函數過程總,直接或間接地調用函數自己,這就是函數的遞歸調用。
    2. 應用:
      1. 二分法:
      2. # 使用遞歸的方式來生成斐波那契數列:一、一、二、三、五、八、1三、2一、34。。。。。
        # 格式如此:F(1)=1,F(2)=1, F(n)=F(n-1)+F(n-2)(n>=3,n∈N*)
        # 數列從第3項開始,每一項都等於前兩項之和。

        def recur_fibo(n):
        if n <=1 :
        return n
        else:
        return (recur_fibo(n-1) + recur_fibo(n-2))

        nterms = int(input('請輸出幾項'))
        if nterms <= 0:
        print('請輸入正數')
        else:
        print('開始輸出斐波那契數列')
        for i in range(1,nterms+1):
        print(recur_fibo(i))
      3. list_a = [1,99,88,77,49,102,53,4,9,80,89]
        list_sorted = sorted(list_a)

        def search(find_num, li):
        if len(li) == 0:
        print('not exits')
        return
        mid_index = len(li) // 2
        mid_num = li[mid_index]
        if find_num > mid_num:
        li = li[mid_index+1:] # 給li 從新賦值一次。
        print(li)
        search(find_num, li)

        elif find_num < mid_num:
        li = li[:mid_index]
        print(li)
        search(find_num,li)
        else:
        print('find it')
        search(0,list_sorted)
  15. 面向過程的程序設計:是一種流水線式的編程思路,是機械式的
    1. 優勢:程序的結構清晰,能夠把負責的問題簡單化
    2. 缺點:擴展性差
    3. 應用場景:linux內核,git,httpd
  16. 名稱空間與做用域
    1. 內置名稱空間
    2. 全局名稱公交
    3. 局部名稱空間
    4. 內置和全局名稱空間屬於全局範圍,全局做用域:全局有效,在任何位置都能被訪問到,除非被刪除(del),不然存活到文件執行結束
    5. 局部名稱空間,局部做用域:局部有效,只能在函數內部被訪問到,在函數執行結束後,就釋放了。
  17.  函數對象(第一類對象):
    1. 函數能夠被當數據來傳遞
    2. 能夠被引用
    3. 能夠看成參數傳遞給另一個函數
    4. 能夠做爲函數的返回值
    5. 能夠看成容器類型的元素
  18. 內置函數
    1. 匿名函數:lambda  只使用一次的函數就用匿名函數
      1. def func(x,y): return x+y 就是有名函數
      2. lambda x,y: x+y
    2. max,min, sorted, zip
      1. def func(x,y):
        return x + y

        # 等同於 func
        lambda x, y: x+y

        #
        salary = {
        'egon': 3000,
        'alex': 100000,
        'better': 20000000,
        'hello': 2000
        }

        print(max(salary)) # 默認按照key值進行比較,最大的值輸出來
        print(max(salary, key=lambda x: salary[x])) # 按照 value值進行排序,將最大的 key 值輸出來
        print(min(salary, key=lambda x: salary[x]))
        print(sorted(salary, key=lambda x: salary[x])) # 按照value值從小到大進行排序,而後輸出 key值。
        print(sorted(salary, key=lambda x: salary[x], reverse=True)) # 按照value值從大到小進行排序,而後輸出 key值。
        # res = zip(salary.values(), salary.keys())  # 生成元組對象。
        # print(list(res))
    3. map, reduce, filter
      1. # map 映射函數,列表+一個 SB 後綴
        #
        l = ['alex', 'wupeiqi', 'yuanhao']

        g = map(lambda x: x + 'SB', l)
        print(list(g))

        # num元素各自平方 一下
        num = [2, 4, 9 ,10]

        n = map(lambda x: x**2, num)
        print(list(n))


        # reduce 合併函數(累積函數),在python2裏面,是做爲內置函數存在的,在python3裏面,則放在了 functools 裏面。應用場景:hadloop 大數據
        from functools import reduce
        numlist = [1,3,5,7,9]
        # 求全部元素相加只和
        sum = reduce(lambda x,y: x+y, numlist, 10) # 第一個參數是個函數:lambad,第二個參數是一個迭代器。
        # 第三個參數是初始值,若是默認沒有的話,則爲:1+3+5+7+9。若是有初始值的話,則爲:10+1+3+5+7+9
        print(sum)
        # filter() 函數用於過濾序列,過濾掉不符合條件的元素,返回由符合條件元素組成的新列表。
        # 該接收兩個參數,第一個爲函數,第二個爲序列,序列的每一個元素做爲參數傳遞給函數進行判,而後返回 True 或 False,
        # 最後將返回 True 的元素放到新列表中

        # 應用1: 過濾出 以SB爲結尾的 列表元素
        l = ['w_SB', 'b_SB', 'c', 'd_SB']

        g = filter(lambda x: x.endswith('SB'), l)
        print(list(g))

        # 應用2:過濾出列表中全部的奇數

        l1 = [1,2,3,4,5,6,7,8]

        def is_odd(n):
        return n % 2 == 1

        new_list = filter(is_odd, l1)

        print(list(new_list))

        # 應用3:過濾出1~100中平方根是整數的數:

        import math

        def is_sqr(x):
        return math.sqrt(x) %1 == 0

        sqr = filter(is_sqr, range(1,101))

        print(list(sqr))
  19. 生成器
    1. 概念:只要函數體包含yield關鍵字,該函數就是生成器函數。生成器函數就是迭代器
    2. yield的功能:
      1. 至關於爲函數封裝好__iter__和__next__
      2. return只能返回一次值,函數就終止了,而yield能返回屢次值,每次返回都會將函數暫停,下一次next會從上一次暫停的位置繼續執行
    3.  yield的兩種形式
      1. 語句形式:yield 1
      2. 表達式形式:x = yield,下面是表達式形式的使用方法

        1. def eater(name):
          print(' %s ready to eat' % name)
          while True:
          food = yield
          print('%s start to eat %s' % (name, food))

          g = eater('zhang')
          next(g) # next() 就至關於 g.send(None),執行 g.send() 以前必須next(g)一次,或者執行 g.send(None)一次。
          g.send('wo')


          # 能夠嘗試用一個裝飾器,在執行eater() 以前,就初始化,執行了,g.send(None),以下所示:

          def init(func):

          def wrapper(*args, **kwargs):
          g = func(*args,**kwargs)
          next(g)
          return g
          return wrapper

          @init
          def eater(name):
          print('%s ready to eat' % name)
          while True:
          food = yield
          print('%s start to eat %s' % (name, food))

          g = eater('zhang') # 輸出:zhang ready to eat
          g.send('shit') # 輸出:zhang start to eat shit
          print(g.send('shit2')) # 會輸出 None ,緣由是 yield 後面沒有值,若是想要輸出值, yield後面須要有值。

          # 若是每次打印上了什麼菜。就須要在yield後面加上數據
          def init(func):

          def wrapper(*args, **kwargs):
          g = func(*args,**kwargs)
          next(g)
          return g
          return wrapper

          @init
          def eater(name):
          print('%s ready to eat' % name)
          foodlist = []
          while True:
          food = yield foodlist
          foodlist.append(food)
          print('%s start to eat %s' % (name, food))



          g = eater('zhang') # 輸出:zhang ready to eat

          #g.send 表示先把shit 賦值給yield,而後由yield再賦值給 food
          g.send('shit') # 輸出:zhang start to eat shit
          print(g.send('shit2')) # 會輸出 None ,緣由是 yield 後面沒有值,若是想要輸出值, yield後面須要有值。
          print(g.send('shit3'))
    4. # 經過yeild來實現  【grep -rl 'python' /root 】這個linux命令,意思是:經過遞歸的方式 找到root目錄下全部包含 python 內容的文件名


      # os.walk 方法是用來遍歷路徑的。 r 參數表示用路徑用"原生字符串"進行遍歷 。意思是"\" python 解釋器就不要處理了,r=raw-string。
      # 在windows環境須要用 r。在linux下則不須要了
      import os

      # address = os.walk(r'/Users/zhangzhihui/Desktop/Python/Basic/A')

      #
      # def search(search_path):
      # address = os.walk(search_path)
      # for par_dir, _, files in address: # 這裏有三個值,【par_dir, _, files】par_dir 表示父目錄,
      # # _表示子目錄(不須要子目錄的話,用_表示就能夠了),files表示子文件
      # for file in files:
      # file_abs_path = par_dir + '/' + file
      # print(file_abs_path)
      #
      # search('/Users/zhangzhihui/Desktop/Python/Basic/A')

      # 上面的方法只能search一次,若是須要屢次執行 search的話,就須要用 yield 方法了,由於yield生成器函數每次都須要執行一次 next(),
      # 不然就會報錯,因此須要加一個裝飾器,讓裝飾器來每次執行一下 next()方法。 以下代碼所示:
      def init(func):
      def wrapper(*args, **kwargs):
      res = func(*args, **kwargs)
      next(res)
      return res
      return wrapper

      # @init
      # def search():
      # while True:
      # search_path = yield
      # address = os.walk(search_path)
      # for par_dir, _, files in address:
      # print(par_dir)
      # for file in files:
      # file_abs_path = par_dir + '/' + file
      # print(file_abs_path)

      # g = search() #search()就是一個生成器
      # g.send('/Users/zhangzhihui/Desktop/Python/Basic') # 此時會將 該目錄下的全部文件都遍歷出來

      # 寫一個open函數,源源不斷的讀取傳過來的路徑,而後打開路徑下的文件。
      # @init
      # def opener():
      # while True:
      # file_abs_path = yield # 生成器 send一次,會傳一次值給 yield 而後賦值給 file_abs_path
      # print(file_abs_path)
      # # with open(file_abs_path,encoding='utf-8') as f:
      # # pass
      #
      # o = opener()
      # o.send('/Users/zhangzhihui/Desktop/Python/Basic/A')
      # o.send('/Users/zhangzhihui/Desktop/Python')
  20. 迭代器
    1. 概念:重複+上一次迭代的結果爲下一次迭代的初始值。重複的過程稱爲迭代,每次重複即一次迭代,而且每次迭代的結果是下一次迭代的初始值
    2. 爲何要有迭代器:
      1. 對於沒有索引的數據類型,必須提供一種不依賴索引的迭代方式
    3. 迭代器優缺點:
      1. 優勢:提供一種不依賴索引的迭代方式;節省內存
      2. 缺點:沒法獲取長度;一次性
  21. 裝飾器
    1. 定義:修飾別人的工具,修飾指的是:添加功能;工具指的是:函數。
      1. 裝飾器自己是任何可調用的對象(加括號就能夠執行的函數)
      2. 被裝飾得對象也能夠是任意可調用的對象
    2. 爲何要用裝飾器:
      1. 開發封閉原則:對修改是封閉的,對擴展是開放的。
      2. 裝飾器就是爲了在不修改源代碼以及調用方式的前提下,爲其添加新功能
    3. 裝飾器的格式就是一個:閉包函數
    4. 應用:
      1. import time

        #定義一個函數,延遲3秒 打印出:I love you。若是在不修改 index的狀況下,調用index時,能夠打印出運行時間,此時就須要運用到裝飾器。
        # def index(a):
        # time.sleep(3)
        # print ('I love you')
        # index()

        # 定一個裝飾器(裝飾器就是一個函數,格式至關於閉包函數的格式)
        def timer(func):
        def wrapper():
        start_time = time.time()
        func()
        end_time = time.time()
        run_time = end_time-start_time
        print (run_time)
        return wrapper

        @timer # @timer 就是裝飾器的調用方法,至關於 index = timer(index)
        def index():
        time.sleep(3)
        print ('I love you')

        #此時直接調用 index 函數時,就能夠在不修改index的狀況下,爲其添加新功能。
        index()
  22. 閉包函數
    • 定義:在函數內部使用,包含對外部做用域而非全局做用域的引用。該內部函數就稱爲:閉包函數。
    • eg:f2() 函數就被稱爲閉包函數
      def f1():
      x = 2
      def f2():
      print (x)
      return f2

      f = f1()
      f()
    • 閉包函數的應用:惰性計算,想何時用的時候,直接 "函數名+()" 就可執行:baidu()
    • # 在函數內部使用,包含對外部做用域而非全局做用域的引用
      # get() 函數包含了對外部做用域的引用:url
      from urllib import urlopen

      def index(url):

      def get():
      res = urlopen(url).read()
      return res

      return get

      baidu = index('http://www.baidu.com')
      print (baidu())

      # 查看閉包函數引用的值,只要是閉包函數就有一個:__closure__ .它的結果是一個 cell。

      url = baidu.__closure__[0].cell_contents
      print (url)

 

 

 

=================第三天相關筆記=====================linux

  1. 函數
    • 按照有參和無參能夠將函數調用分兩種:有參函數 和 無餐函數。
      • foo() #定義時無參,調用時也無需傳入參數
      • bar('egon') #定義時有參,調用時也必須有參數
    • 在python中函數分爲:內置函數和自定義函數
    • 定義函數的三種形式
      • 無參數函數:若是函數的功能僅僅只是執行一些操做而已,就定義成無參函數,無參函數一般都沒有返回值
      • 定義有參函數:函數的功能的執行依賴於外部傳入的參數,有參函數一般都有返回值
      • 空函數
    • 函數的使用包含兩個階段:定義階段和使用階段
    • 爲何要定義函數?:
      • 先定義後使用,若是沒有定義而直接使用,就至關於引用了一個不存在的變量名

=================次日相關筆記=====================git

  1. String 字符串
    • name = 「zhangZhiHUI」
      • v = name.casefold()  #將全部的字符都變成小寫,包括德語等其餘語言,
      • v = name.lower() # 只將英文字符變成小寫 
      • v = name.upper() # 將全部的字母都大寫
      • v = name.swapcase() # 將全部的字符進行大小寫轉換。
      • v = name.center(20,’@‘) #參數1表示總長度。參數2: 表示空白處填充的字符(長度爲1)
      • v = name.count('Z’) #表示傳入值在字符串中出現的次數。
      • v = name.count(‘Z’,2) #第一個參數表示:起始位置(索引)。
      • v = name.count(‘Z’,2,5) #第二個參數表示:結束位置(索引)。
      • v = name.startswith(‘zh’) # 是否以xx開頭
      • v = name.endwith(‘UI’) #是否以xx結尾
      • v = name.find(‘a’) # 找字母a,若是找到,返回字母a所在字符串中的位置,找不到返回 -1
      • v = name.index(‘a’) #找字母a,若是找到,返回字母a所在字符串中的位置,找不到會報錯~ 建議用find。
      • v = name.isidentifier() #是不是標誌符,eg:class 
      • v = name.isdecimal() #判斷是不是數字,eg: ‘123'
      • v = name.isdigit() #判斷是不是數字:eg:’123’ 2⃣️ 都能判斷
      • v = name.isnumeric() #判斷是不是數字:eg:’123’,’二’,2⃣️
      • v = name.isalnum() #判斷是不是字母加數字。
      • v = name.isalpha() #判斷是不是字母
    • 字符串的格式化
      • name = "我是:%s;年齡:%s;性別:%s"
      • name = "我是:{0};年齡:{1};性別:{2}"
      • v = name.format(「zhang",19,'都行')
      • name = "我是:{name};年齡:{age};性別:{gender}"
      • v = name.format(name='李傑',age=19,gender='隨意')
      • name = "我是:{name};年齡:{age};性別:{gender}"
      • v = name.format_map({'name':"李傑",'age':19,'gender':'中'})
    • 字符串的鏈接
      • name = ‘alex’
      • v = ‘_’.join(name) #輸出爲:a_l_e_x
    • 字符串的替換
      • name = ‘zhangsbzhihueisbgoushi’
      • v = name.replace(’SB’,’love’) #將SB替換成love
      • v = name.replace(’SB’,’love’,1) #將第一個SB替換成love
  2. List 列表 可變類型
    • 擴展原列表
      • user_list = ['zhang','zhihui','alex']
      • user_list.extend(['zhao','yiwei','zhang’])
      • user_list = ['zhang','zhihui',’alex’,'zhao','yiwei','zhang’]
      • user_list.index(‘zhang’) 。查到的話,返回索引值。查不到的話,報錯。
      • user_list.reverse() #整個列表的反轉
      • user_list.sort() #整個列表按照ascii碼排序eg:a~z 從小到大
      • user_list.sort(reverse=True) 從大到小進行排序
  3. Tuple 元組,不可被修改的列表,不可變類型
    • user_tuple = (‘alex’,’eric’,’zhang’,[‘a’,’b’,’c’],
    • tuple的子元素不能夠被變動,但孫子元素是能夠被變動的。
    • 元祖的最後,須要加一個逗號
  4. Dict 字典--可變類型,字典能夠嵌套;字典的key必須是不可變類型
    •  深淺copy
    • dic.get(‘key’) #經過key來獲取指定的value值。若是key不存在,則返回None
    • v=dic.pop(‘key’) #刪除key和key對應的value,並將value值返回給v
    • v=dic.popitem() #隨機刪除鍵值對,並將鍵值對返回給v
    • dic.setdefault(‘key’,’value) #若是字典中不存在key值,則將key,value增長到字典中。若是存在key值,則不進行任何操做。
    • dic.update({‘k1’:’v1,’k5’:’v5}) #批量修改和更新,若是有對應的key,則update,若是沒有對應的key,則新增入字典。
    • dic = dict.fromkeys([‘k1’,’k2’,’k3’],123) #新建一個全部value都等於123的字典
  5. Set 集合 --不可重複的列表,可變類型
    • s1 = {"alex",'eric','tony','李泉','李泉11’}
    • s2 = {"alex",'eric','tony','劉一’}
    • v = s1.difference(s2) # 表示s1中存在而s2中不存在的元素
    • s1.difference_update(s2) #表示s1中存在而s2中不存在的值。先將s1清空,在將值從新付值到s1中 。v={'李泉','李泉11’}
    • v = s1.symmetric_difference(s2) #去除s1和s2共有的值,返回給v
    • v = s1.intersection(s2) #s1和s2的交集
    • v = s1.union(s2) #s1和s2的並集
    • s1.discard(‘alex’) #將alex元素移除
    • s1.update({‘a’,’b’,’c’}) #重複的值不作操做,不同的值添加進s1
  6. Enumerate枚舉,會額外聲稱一列有序的數字
    • user_list = ['zhang','zhi','hui','zhaoyiwei’]
      • for i,ele in enumerate(user_list,1): #參數1表示從數字1開始輸出有序的數字
      • print(i,ele)
      • 輸出結果:
        1 zhang
        2 zhi
        3 hui
  7. 其餘
    • range()函數在2.7裏面,會當即生成全部在範圍內的數字,缺點,當數值範圍較大時,會引發內存Crash。而在3.x裏面,不會當即生成,只有循環迭代時,纔會一個一個生成,
      • 輸出10~0
      • for i in range(10,0,-1)
      • 輸出 1,3,5,7,9
      • for i in range(1,10,2)

 

 

 

=================第一天相關筆記=====================shell

  1. Python種類和其餘語言的對比
    • CPython:代碼 -> C 字節碼 -> 機器碼 (一行一行進行編譯執行)
    • PyPy:代碼 -> C 字節碼 -> 機器碼 所有轉換完 再執行->執行
    • 其餘Python(Jython): 代碼 -> 其餘字節碼 -> 機器碼
  2. 字符編碼:
    • ascii :8位二進制數來表示 256種可能的字符,00000000 2**8=256
    • unicode 萬國碼: 至少兩個字節起,佔用內存空間比較大。
    • utf-8 :彈性存儲,是對萬國碼的壓縮。中文佔三個字節。00000000 00000000 00000000
    • gbk,gb2312:中文須要兩個字節。00000000 00000000  
  3. 變量
    • 字母
    • 數字(變量不能以數字開頭)
    • 下劃線
    • 不能使用關鍵字來命名變量
    • 變量名須要設置一個有意義的,能夠經過下劃線方式。eg:usr_info
  4. Python數據類型
    • 布爾值:
      • 數字:只有數字0是 False,其餘都是 True
      • 字符串:只有""是 False,其餘的都是 True,包括" "。有空格也表示 True
  5. 佔位符
    • 相關格式:
      • name = '我叫: %s,性別: %s,年齡: %d' % ('張志輝', '男', 18)
  6. 運算符
    • and or 運算符
      • 1 == 1 and 1 > 2 or 1 == 4  False 若是遇到and,左側正確再繼續向後看,若是右側也正確,則就表示正確。or後面的就不用看了
      • 1 == 1 or 1 > 2 and 1 == 4  True   從左到右。若是遇到or,若是左側是True,右側就不用看了,直接忽略,打印出來是True。
      • 原理:and 和 or 優先級相等,
  7. String相關操做
    • 移除空格和換行符
      • val = ' alex ' 。
        • val.strip()   #移除左右空格,包括回車換行。
        • val.lstrip()  #移除左側空格,rstrip()表示移除右側空格
    • 分割
      • val = 'zhang|zhihui|9|10'
        • val.splict('|')  #經過 | 來分隔,分隔出list:['zhang', 'zhihui', '9','10']
        • val.splict('|',1)  #表示只分隔左側第一個|,分隔出list:['zhang', 'zhihui|9|10']。如是2,則表示分隔左側兩個 |
    • 長度&索引
      • len(val)  長度
      • val[0]     索引
    • 切片
      • name = 'zhangzhihui'  
      • name[0:5]  #打印索引 0,1,2,3,4 五個字符。
      • name[0:5:2]  #打印索引 0,2,4 三個字符,步長爲2.
  8. List 列表
    • 刪除
      • n = [ 'zhang', 'zhi', 'hui' ]
      • v = n.remove('zhi')  #根據value刪除
      • v = del(n[0])   #按照索引刪除
    • 更新
      • n = [ 'zhang', 'zhi', 'hui' ]
      • n[1] = 'zhao'
  9. 字典
    • 建立
      • 1 user = {
        2     'name': 'zhiHui',
        3     'age': 18,
        4     'gender': 'male'
        5 }
    • 增長&更新
      • user['age'] = 34         #若是沒有該key,則新增;若是有該key,則更新。
    • 索引
      • n = user['name']       #能夠經過key獲取值。獲取值爲:zhiHui
    • 刪除
      • del user['name']       #經過key來刪除
    • 循環
      • # 打印字典裏的key
        for item in val.keys():
            print(item)
        
        # 打印字典裏的values
        for item in val.values():
            print(item)
        
        # 打印鍵值對
        for key, value in val.items():
            print(key, value)
    • 相互嵌套
      •  1 user_dict = {
         2     'k1': 'value1',
         3     'k2': {'kk1': 'vv1', 'kk2': 'vv2', 'kk3': 'vv3'},
         4     'k3': 123,
         5     'k4': ['alex', 'eric', ['a', 'b', 'c'], '張志輝', {'k11': 'v11'}]
         6 }
         7 
         8 # K4下的list列表中append一個元素
         9 user_dict['k4'][2].append('dog')
        10 print(user_dict)
        11 
        12 # 經過索引獲得其中的一個元素的value
        13 n = user_dict['k4'][4]['k11']
        14 print(n)
        15 
        16 # 經過key更新 value
        17 user_dict['k2']['kk1'] = 'zhang'
        18 print(user_dict)
        19 
        20 # 插入key and value
        21 user_dict['k5'] = 7899
        22 print(user_dict)
相關文章
相關標籤/搜索