Python的學(xué)習(xí)

Python 廖雪峰: https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

Python 的安裝及.........配置(Mac 系統(tǒng)下)

Mac 系統(tǒng)下的安裝

  1. 安裝 Homebrew

    ~ 理解 homebrew 和 npm 區(qū)別

    homebrew: osx的軟件管理工具, 軟件管理助手, 可以安裝Chrome瀏覽器等可視化工具

    npm: node.js的程序/模塊管理工具, 服務(wù)于JavaScript社區(qū)

    ~ 安裝 homebrew: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

  2. 安裝 Python

    ~ python2.x 和 python3.x

    python2.x: Mac 系統(tǒng)自帶 Python2.7(老, 被取代)

    python3.x: ① 官網(wǎng)下載安裝 ② 通過 brew brew install python3 安裝

  3. Python 解釋器(交互式命令行)

    1. CPython(下載安裝 python 即完成): 解釋器是用 C 語言開發(fā)的向胡,所以叫 CPython留攒。在命令行下運(yùn)行 python 就是啟動 CPython 解釋器

    2. 使用

    終端中運(yùn)行python, 啟動 python2.x

    終端中運(yùn)行python3, 啟動 Python3.x

    CPython 使用>>>, 作為提示符, 使用 exit()作為退出

  4. 文本編輯器 (VScode)

    1. 安裝拓展 Python

    2. vscode 報(bào)錯: Linter pylint is not installed(代碼規(guī)范的插件)

    ~ 參考: https://blog.csdn.net/yh1061632045/article/details/81665446

    ~ 手動切換 python2.7 --> python3.7(地址是: /usr/local/bin/python3)

    ~ 配置 vscode, 設(shè)置python.pythonPath: /usr/local/bin/python3

    ~ 然后點(diǎn)擊install pylint, 安裝完成 vscode 就不彈出提示, 同時(shí)能代碼提示

win 系統(tǒng)下的安裝

  1. 官網(wǎng)下安裝

  2. 勾選Add Python 3.7 to PATH, 然后安裝即可

  3. 在命令提示符中, python會出來>>>即代表安裝成功

  4. 可能報(bào)錯code2305

第一個 Python 程序

  1. 步驟

    1. 添加 .py文件, 編寫print('hello world!')

    2. 執(zhí)行.py 文件

      1. 利用 python 命令: cd 到文件所在目錄 -> 終端執(zhí)行python demo.py -> 打印出結(jié)果(win, mac)

      2. 直接執(zhí)行.py 文件: cd 到文件目錄 -> 終端中chmod a+x demo.py 給與文件可執(zhí)行的能力 -> 終端中 ./demo.py -> 打印結(jié)果(mac系統(tǒng))

      3. 直接執(zhí)行.py文件: 終端中 demo.py -> 即會執(zhí)行(win系統(tǒng))

  2. 交互模式 和 直接執(zhí)行.py 文件的區(qū)別

    1. 交互模式: 啟動 Python 解釋器, 輸入一行解釋一行, 不做保存(適合單端代碼的測試)

    2. .py 文件: 一次性執(zhí)行完畢, 不給打斷

  3. print()輸出

    1. 逗號以空格輸出: print('hello', 'world') -> 逗號以空格輸出 -> hello world

    2. 自動計(jì)算: print(300 + 300) -> 600(可以做計(jì)算)

    3. print('300 + 100 =', 300 + 100) -> 300 + 100 = 600

  4. input 和 變量

    1. input 默認(rèn)輸出 str, 所以如果需要轉(zhuǎn)化成整數(shù)需要用到int(input())

    2. 當(dāng)int('abc'), 發(fā)現(xiàn) abc 不能轉(zhuǎn)化成整數(shù)的時(shí)候, 就會報(bào)ValueError 的錯

    3. name = input()回車 -> >>>等待輸入值 -> name 存儲你輸入的值 -> >>>name -> 打印輸入值

Python 代碼運(yùn)行助手

  1. 作用: 讓你在線輸入 Python 代碼镐作,然后通過本機(jī)運(yùn)行的一個Python腳本(就是learning.py)來執(zhí)行代碼, 直接在網(wǎng)頁輸出結(jié)果

  2. 終端執(zhí)行python learning.py -> 終端輸出Ready for Python code on port 39093...等代表運(yùn)行成功

  3. 打開https://local.liaoxuefeng.com:39093/, 就是 Python 的在線編輯器, 點(diǎn)擊 run 即可輸出結(jié)果

  4. 網(wǎng)頁 run 不輸出結(jié)果的話, Ctrl + c 中斷, 再執(zhí)行步驟 2

基本語法

基礎(chǔ)

  1. 基礎(chǔ)

    1. # : 注釋
    2. : : 當(dāng)語句以冒號:結(jié)尾時(shí)票灰,縮進(jìn)的語句視為代碼塊(相當(dāng)于js的大括號)
    3. Python 大小寫敏感
  2. 數(shù)據(jù)類型和變量

    1. 整數(shù): 十進(jìn)制, 二進(jìn)制, 十六進(jìn)制
    2. 浮點(diǎn)數(shù): 小數(shù)
    3. 字符串: ', "
    4. 轉(zhuǎn)義符: 'I\'m \"OK\"!' => I'm "OK"!, \n表示換行派任,\t表示制表符违柏,字符\本身也要轉(zhuǎn)義为肮,所以\\表示的字符就是\
    5. 不轉(zhuǎn)義r'', ''內(nèi)部字符串不轉(zhuǎn)義, 直接輸出
    6. 換行'''...''', 多行時(shí), 比\n來的方便
          # 交互命令行內(nèi)... 是提示符, 并不需要手動輸入
          print('''line1
          ... line2
          ... lin3''')
          # .py文件中
          print('''line1
          line2
          line3''')
          # 還可以 print(r'''line1
          # line2
          # line3''')
      
    7. 布爾值(True, False) 和 布爾運(yùn)算
        # 布爾值, 注意大小寫
        >>> False
        False
        # 布爾運(yùn)算
        >>> 3 > 2
        True
        # and帐萎、or和not運(yùn)算
        >>> True and False
        False
        >>> True or False
        True
        >>> not 1 > 2
        True
      
    8. 空值: None
    9. 變量: 變量名必須是大小寫英文、數(shù)字和_的組合敞曹,且不能用數(shù)字開頭
    10. 常量: 通常用全部的大寫
    11. 除法: /, 得到的都是浮點(diǎn)數(shù), >>> 9/3 -> 3.0
    12. 地板除: //, 只取結(jié)果的整數(shù)部分
    13. 取余數(shù): %

    總結(jié): 萬物皆對象, Python 對整數(shù)無大小限制,對浮點(diǎn)數(shù)超出一定范圍直接顯示inf(無限大)

字符串編碼

  1. ord(), 函數(shù)獲取字符的整數(shù)表示, 英文轉(zhuǎn) ascii 碼的數(shù)字

  2. chr(), 函數(shù)把編碼轉(zhuǎn)換為對應(yīng)的字符, 相反

  3. b'ABC', 把 Python 的 str 轉(zhuǎn)成以字節(jié)為單位的 bytes, ABCb'abc', 一個是 str, 一個是 bytes, 每個字符只占一個字節(jié)

  4. str通過encode()方法可以編碼為指定的 bytes

      >>> 'ABC'.encode('ascii')
      b'ABC'
      >>> '中文'.encode('utf-8')
      b'\xe4\xb8\xad\xe6\x96\x87'
      # 中文可以轉(zhuǎn)成utf-8, 但是不可以轉(zhuǎn)成ascii, 因?yàn)橹形某龇秶?  # 在bytes中账月,無法顯示為ASCII字符的字節(jié),用\x##顯示澳迫。
      >>> '中文'.encode('ascii')
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
    
  5. bytes通過decode方法, 轉(zhuǎn)成 str

      >>> b'ABC'.decode('ascii')
      'ABC'
      >>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
      '中文'
      # 如果bytes中包含無法解碼的字節(jié)局齿,decode()方法會報(bào)錯
      # 如果bytes中只有一小部分無效的字節(jié),可以傳入errors='ignore'忽略錯誤的字節(jié)
      >>> b'\xe4\xb8\xad\xff'.decode('utf-8', errors='ignore')
      '中'
    
  6. len() 函數(shù)計(jì)算的是 str 的字符數(shù)橄登,如果換成 bytes抓歼,len()函數(shù)就計(jì)算字節(jié)數(shù)

      >>> len(b'ABC')
      3
      >>> len(b'\xe4\xb8\xad\xe6\x96\x87')
      6
      >>> len('中文'.encode('utf-8'))
      6
    
  7. str 和 bytes 的互相轉(zhuǎn)換。為了避免亂碼問題拢锹,應(yīng)當(dāng)使用 UTF-8 編碼對 str 和 bytes 進(jìn)行轉(zhuǎn)換

      # 為了告訴Linux/OS X系統(tǒng)谣妻,這是一個Python可執(zhí)行程序,Windows系統(tǒng)會忽略這個注釋卒稳;
      # 告訴Python解釋器蹋半,按照UTF-8編碼讀取源代碼,否則充坑,你在源代碼中寫的中文輸出可能會有亂碼减江。
      #!/usr/bin/env python3
      # -*- coding: utf-8 -*-
    
  8. 格式化(有點(diǎn)像 js 的模板字符串)

      # %s:字符串,  %d:整數(shù),  %f: 浮點(diǎn)數(shù),  %x:十六進(jìn)制整數(shù)
      # 需要替換的地方依次填寫參數(shù)
      # %% 代表轉(zhuǎn)義 %
      >>> 'hello, %s, you have $%d' % ('bin.wang', 100)
      'hello, bin.wang, you have $100'
    
  9. 計(jì)算機(jī)儲存使用 Unicode染突,只有在傳輸?shù)臅r(shí)候才轉(zhuǎn)換成 UTF-8

  10. str 不可變性

      >>> a = 'abc'
      # replace方法
      >>> a.replace('a', 'A')
      # 變的是變量a, 字符串'abc'并沒有變
      >>> a
      'Abc'
    

list 和 tuple

  1. list(類比 js 數(shù)組)

      >>> list = ['one', 'two', 'three']
      # 求得list長度
      >>> len(list)
      3
      # list下標(biāo)代表具體某個值
      >>> list[len(list) - 1]
      'three'
      # -1 代表最后一個, -2代表倒數(shù)第二個
      >>> list[-1]
      # 正向反向越界都報(bào) `IndexError` 的錯
    
  2. list 的方法

    1. append(): list.appen('test'), 末尾追加

    2. pop(): list.pop(), 刪除末尾, list.pop(1), 刪除下標(biāo)為 1 的那個

    3. insert: list.insert(1, 'test'), 在索引 1 的地方插入

    4. sort(): list.sort(), 根據(jù) ascii 大小排序

  3. tuple(元組)

    1. 跟 list 類似, 但是 tuple 一旦初始化就不能修改, 取得方式一致, 但是沒有 list 的方法

        >>> tuple = (1, 2, 3)
        >>> tuple[0]
        1
        # 注意當(dāng)python只有一個元素的元組時(shí)候, 必須帶上逗號, 以免識別成數(shù)學(xué)的括號運(yùn)算
        >>> t = (1, )
      
    2. 關(guān)于 tuple 的不可變

        # 元組指向list是一直不變的, 只是list可變
        >>> t = ('a', 'b', ['c', 'd'])
        >>> t[2][0] = 'X'
        >>> t[2][1] = 'Y'
        >>> t
        ('a', 'b', ['X', 'Y'])
      

條件判斷

  1. 條件判斷

      age = 20
      # 每個條件判斷以 : 分割, elif 是 else if的縮寫
      if age >= 18:
        print('成年人')
      elif age >= 16:
        print('青少年')
      else:
        print('少年')
    

循環(huán)

  1. for...in循環(huán)(list, tuple, dict都可使用)

      name = ['Bob', 'Jack']
      # Python 以 : 代替JS的 {}
      for key in name:
        print(key)
    
  2. range()函數(shù),可以生成一個整數(shù)序列

  3. list()函數(shù), 可以轉(zhuǎn)換為 list

      # range 生成從0開始小于5的整數(shù), list把他們合成數(shù)組
      >>> list(range(5))
      [0, 1, 2, 3, 4]
    
  4. while 循環(huán), 只要條件滿足辈灼,就不斷循環(huán)

      num = 5
      sum = 0
      while num > 0:
        sum = sum + num
        num = num - 1
      print(sum)
    
  5. break, 可提前結(jié)束循環(huán)

  6. continue語句跳過某些循環(huán)

dict 和 set

  1. dict, 官網(wǎng)說像 map, 個人覺得像對象

      >>> d = {'Nacy': 83, 'Bob': 93}
      >>> d['Bob']
      93
      # 多次賦值, 會覆蓋
      >>> d['Bob'] = 98
      >>> d['Bob']
      98
    
  2. dict 的 key 值

    1. key 值不存在, 會報(bào)錯KeyError

    2. 判斷 key 值存在

        b = {'Bob': 123}
        # 第一種in
        >>> 'test' in b
        False
        # 第二種 get()方法,返回None 在交互模式下None不顯示
        >>> b.get('test')
        # 不顯示
        >>> b.get('Bob')
        123
        >>> b.get('test', -1)
        -1
        >>> b.get('Bob', -1)
        123
      
    3. dict 和 list 的區(qū)別

      1. dict: key 找 value, 根據(jù) key 值算出(哈希算法)'頁碼', 再根據(jù)頁碼查找 value, 所以占用內(nèi)存較多
      2. list: 下標(biāo)找 value, 查找是從頭到尾, 直到找到, list 越長, 耗時(shí)慢
    4. 刪除一個 key, pop()方法, 對應(yīng)的 value 也會被刪除

      相反, 新增的話直接是d['Bob'] = '123', 即可

  3. set

    1. 傳入 list 作為輸入集合, 重復(fù)元素自動被過濾, 只存儲 key, 不存 value, 且無序

        >>> s = set([1, 1, 2, 2, 3, 3])
        >>> s
        {1, 2, 3}
        # 通過add(key)添加新key, 重復(fù)添加沒效果
        >>> s.add(4)
        >>> s
        {1, 2, 3, 4}
        # 通過remove(key)方法可以刪除元素
        >>> s.remove(1)
        >>> s
        {2, 3, 4}
      
    2. set 可以看成無序和無重復(fù)元素的集合, 因此份企,兩個 set 可以做數(shù)學(xué)意義上的交集、并集等操作

        >>> s1 = set([1, 2, 3])
        >>> s2 = set([2, 3, 4])
        >>> s1 & s2
        {2, 3}
        >>> s1 | s2
        {1, 2, 3, 4}
      

函數(shù)

內(nèi)置函數(shù)

  1. 參考地址: https://docs.python.org/3/library/functions.html

  2. 求絕對值函數(shù): abs(num) abs(-100) -> 100

  3. 求最大值: max(num1, num2) max(1, 2, -3) -> 2

  4. 類型轉(zhuǎn)換, 交互模式下, help(hex)查看 hex 函數(shù)作用

      >>> int('123')
      123
      >>> int(12.84)
      12
      >>> int('abc')
      # int第二個參數(shù)base是代表進(jìn)制, 第一個參數(shù)是16進(jìn)制, 轉(zhuǎn)成十進(jìn)制, 16^1 + 6 = 22
     >>> int('16', base=16)
     22
     >>> int('123', 8)
     83
      # 報(bào)錯 ValueError
      >>> float('12.34')
      12.34
      >>> str(1.23)
      '1.23'
      >>> str(100)
      '100'
      >>> bool(1)
      True
      >>> bool('')
      False
    

自定義函數(shù)

  1. def定義函數(shù)

      # 在交互模式下直接敲出函數(shù)
      # 沒有定義return的, 最后還是會return None
      def my_abs(x):
        if x >= 0:
          return x
        else:
          return -x
      # 在交互模式下 import 引入函數(shù)
      >>> from demo(文件名不帶.py) import my_abs(函數(shù)名)
      >>> my_abs(-10)
      10
    
  2. 定義空函數(shù)

      def nop():
        # pass相當(dāng)于占位符,代表不干啥事, 不填寫會報(bào)錯
        pass
    
  3. 檢查參數(shù)

      def my_abs(x):
      # isinstance判斷參數(shù)類型是不是整數(shù)或者浮點(diǎn)數(shù), 不是就raise 一個錯誤
      if not isinstance(x, (int, float)):
          raise TypeError('參數(shù)錯誤')
      if x >= 0:
          return x
      else:
          return -x
    
  4. 返回多個值

      >>> def Fn(x, y):
            return x, y
      >>> r = Fn('abc', 'cba')
      >>> print(r)
      # 返回多個值其實(shí)返回的是一個tuple, 返回一個tuple可以省略括號
      ('abc', 'cba')
    

函數(shù)的參數(shù)(挺繞的, 多練習(xí))

  1. 位置參數(shù)(必選參數(shù))

      # x必須且依次, 即位置參數(shù)
      def sum (x):
        return x * x
    
  2. 默認(rèn)參數(shù)

    概念: 默認(rèn)參數(shù)必須要用不可變對象

      #必選參數(shù)在前, 默認(rèn)參數(shù)在后
      def sum (x, n = 2, age = 18)
        pass
      # n還是使用默認(rèn)值
      sum(2, age = 16)
      # 默認(rèn)參數(shù)的坑, 默認(rèn)參數(shù)必須指向不變對象巡莹!
      def add_end(L = []):
        L.append('END')
        return L
      # 調(diào)用三次, 會一直加, 原因在: Python函數(shù)在定義的時(shí)候司志,默認(rèn)參數(shù)L的值就被計(jì)算出來了,即[]降宅,因?yàn)槟J(rèn)參數(shù)L也是一個變量俐芯,它指向?qū)ο骩],每次調(diào)用該函數(shù)钉鸯,如果改變了L的內(nèi)容吧史,則下次調(diào)用時(shí),默認(rèn)參數(shù)的內(nèi)容就變了唠雕,不再是函數(shù)定義時(shí)的[]了贸营。
      add_end()
      ['END', 'END', 'END']
      # 修改
      def add_end(L = None):
        if L is None:
          L = []
        L.append('END')
        return L
    
  3. 可變參數(shù)

    概念: 允許傳入0個或若干個參數(shù), 定義時(shí)參數(shù)帶*

      # 定義一個a^2 + b^2...的函數(shù)
      def getSum(*number):
        sum = 0
        for key in number:
          sum = sum + key * key
        return sum
      tuple = (3, 4)
      # 直接傳參, 調(diào)用時(shí)自動組裝成tuple
      getsum(1, 2)
      # 直接拿tuple使用. 記得帶星號
      getSum(*tuple)
    
  4. 關(guān)鍵字參數(shù)

    概念: 允許傳入0個或若干個含參數(shù)名的參數(shù), 調(diào)用時(shí)自動組成dict, 定義和調(diào)用都需要使用**

      def person(name, age, **kw):
        print('name: %s, age: %d, other: %s' % (name, age, kw))
      dict = {'city': 'sz'}
      # kw得到的是dict的拷貝
      person('bin.wang', 18, **dict)
    
  5. 命名關(guān)鍵字參數(shù)

    概念: 為限制關(guān)鍵字參數(shù)名字, key = value, 且不是dict

      # 以*為分割, 后面的為命名關(guān)鍵字參數(shù)
      def person(name, *, city = 'SZ', age)
        print(name, city, age)
      person('test', age = 18)
      # 傳參時(shí), 必須傳入?yún)?shù)名和參數(shù)值, 否則相當(dāng)于多傳了位置參數(shù), 報(bào)錯
      person('test', 18)
      # 命名關(guān)鍵字參數(shù)可以由默認(rèn)值, city
    
  6. 參數(shù)組合

    概念: 參數(shù)定義的順序必須是:必選參數(shù)、默認(rèn)參數(shù)岩睁、可變參數(shù)钞脂、命名關(guān)鍵字參數(shù)和關(guān)鍵字參數(shù)

      def f1(a, b, c=0, *args, **kw):
      >>> f1(1, 2, 3, 'a', 'b')
      a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
      # 通過tuple 和 dict的話, 可簡單到
      >>> args = (1, 2, 3, 4)
      >>> kw = {'d': 99, 'x': '#'}
      >>> f1(*args, **kw)
      a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
      # 必選, 默認(rèn), 命名關(guān)鍵字參數(shù), 關(guān)鍵字參數(shù)
      def f2(a, b, c=0, *, d, **kw):
      >>> f2(1, 2, d=99, ext=None)
      a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
    

遞歸函數(shù)

  1. 函數(shù)內(nèi)部, 調(diào)用本身, 過深的調(diào)用可能導(dǎo)致棧溢出

  2. 棧溢出科普: 計(jì)算機(jī)中函數(shù)的調(diào)用通過棧數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的, 每進(jìn)一個函數(shù), 棧就加一層棧幀, return一次就減少一層棧幀, 當(dāng)函數(shù)調(diào)用過多, 即會棧溢出

  3. python棧溢出報(bào)錯: RecursionError: maximum recursion depth exceeded in comparison

      def getFn(n):
        if n == 1:
          return 1
        return n * getFn(n - 1)
    
  4. 例子: 移動漢諾塔

高級特性

切片(slice)

  1. 對list, tuple, str的數(shù)據(jù)處理

      # 對list或者tuple
      L = []
      n = 0
      while n <= 99:
        L.append(n)
        n = n + 1
      # 生成L是[0-99]的list
      # slice切片, 取索引0到索引3(不包括3), 即0, 1, 2
      >>> L[ : 3]
      >>> [0, 1, 2]
      # L[-1]代表最后一位, 那么包括倒數(shù)第三位, 不包括倒數(shù)第一位
      >>> L[-3: -1]
      >>> [97, 98]
      # 前十位, 每隔5位取一個
      >>> L[ : 10 : 5]
      >>> [0, 5]
      # 所有l(wèi)ist, 隔20取一位
      >>> L[ : : 20]
      >>> [0, 20, 40, 60, 80]
      # 完全復(fù)制一個list
      >>> n = L[ : ]
    
      >>> str = 'mytest'
      # 每隔2位取一位
      >>> str[ : : 2]
      >>> 'mts'
    

迭代

  1. for...in...遍歷也叫迭代, list, tuple, dict, str, generator都可迭代

  2. 迭代的用法

    1. list 和 tuple的迭代

        # 如果迭代的時(shí)候想把下標(biāo)輸出
        # 引用python內(nèi)置的enumerate函數(shù)
        >>> list = [4, 5, 6]
        >>> for index, value in enmurate(list):
        >>> 0 4  1 5  2 6
        # 常見多變量
        >>>  for x, y in [(1, 1), (2, 4)]:
        ...     print(x, y)
        >>> 1 1   2 4
      
    2. dict的迭代

        >>> dict = {'Bob': 18, 'Nancy': 17}
        # 獲取key值
        >>> for key in dict:
        >>> 'Bob' 'Nancy'
        # 獲取value
        >>> for value in dict.values():
        # 獲取key和value值
        >>> for key, value in dict.items():
        >>> Bob 18 Nancy 17
      
    3. str的迭代

        >>> str = 'test'
        >>> for key in str:
        >>> t e s t
      
  3. 檢測可迭代對象(區(qū)別于Iterator, 迭代器)

    1. 概念: 只要是可迭代對象, for循環(huán)就不會報(bào)錯, 通過collections模塊的Iterable類型判斷可迭代對象
      >>> from collections import Iterable
      >>> isinstance([1,2,3], Iterable)
      >>> True
      >>> isinstance('str', Iterable)
      >>> True
      >>> isinstance(123, Iterable)
      >>> False
    

列表生成式

  1. 概念: Python內(nèi)置的用來創(chuàng)建list的生成式
      # list部分
      >>> list(range(1, 6))
      >>> [1, 2, 3, 4, 5]
      # 生成 [1 * 1, 2 * 2, 3 * 3]
      >>> [x * x for x in range(1, 4)]
      >>> [1, 4, 9]
      # 還可以進(jìn)行篩選
      >>> [x * x for x in range(1, 4) if x % 2 == 0]
      >>> [4]
      # 使用兩層循環(huán),可以生成全排列, 即排列組合
      >>> [m + n for m in 'ABC' for n in 'XYZ']
      ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
      # 把list中所有的字符串變成小寫
      >>> list = ['Hello', 'World']
      >>> [s.lower() for s in list]
      >>> ['hello', 'world]
    
      # dict部分
      >>> dict = {'x': 'A', 'y': 'B'}
      >>> [k + '=' + v for k, v in dict.items()]
      >>> ['x=A', 'y=B']
    

生成器(generator)

  1. 概念通過列表生成式, 直接生成的list, 當(dāng)量大時(shí)耗內(nèi)存, 使用生成器按照邏輯邊循環(huán)邊計(jì)算, 節(jié)省空間

  2. 簡單方式

      # 直接把列表生成式改成 簡單的generator 區(qū)別: [] => ()
      >>> g = (x * x for x in [1, 2])
      >>> <generator object <genexpr> at 0x1022ef630>
    
  3. 遍歷每一項(xiàng)

      # 每次調(diào)用next(g)捕儒,就計(jì)算出g的下一個元素的值冰啃,直到計(jì)算到最后一個元素,沒有更多的元素時(shí)刘莹,拋出StopIteration的錯誤
      >>> next(g)
      >>> 1
      >>> next(g)
      >>> 4
      # 沒有了就結(jié)束
      >>> next(g)
      >>> StopIteration
      # 通過 for...in...(常用)
      >>> for n in g
      >>> 1 4
    
  4. 斐波那契

      # 相當(dāng)于 t = (0, 0, 1) => a = t[0]
      >>> n, a, b = 0, 0, 1
      # 關(guān)鍵字yield, 生成generator
      def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1
        return 'done'
      # generator和函數(shù)的執(zhí)行流程不一樣, 函數(shù)是順序執(zhí)行阎毅,遇到return語句或者最后一行函數(shù)語句就返回, 變成generator的函數(shù),在每次調(diào)用next()的時(shí)候執(zhí)行点弯,遇到y(tǒng)ield語句返回扇调,再次執(zhí)行時(shí)從上次返回的yield語句處繼續(xù)執(zhí)行。
    

迭代器

  1. 概念: 可以被next()函數(shù)調(diào)用并不斷返回下一個值的對象稱為迭代器:Iterator, 生成器都是Iterator對象, 但list抢肛、dict狼钮、str雖然是Iterable(可迭代),卻不是Iterator(可迭代對象)

  2. dict, list, tuple, str數(shù)據(jù)類型為何不是Iterator ?

    Iterator對象表示的是一個數(shù)據(jù)流, 被next()函數(shù)調(diào)用時(shí)不斷返回下一個數(shù)據(jù), 直到?jīng)]有數(shù)據(jù)時(shí)拋出StopIteration錯誤, 我們不能提前知道序列長度, 所以Iterator的計(jì)算是惰性的捡絮,只有在需要返回下一個數(shù)據(jù)時(shí)它才會計(jì)算. Iterator甚至可以表示一個無限大的數(shù)據(jù)流熬芜,例如全體自然數(shù)。而使用list是永遠(yuǎn)不可能存儲全體自然數(shù)的.

  3. 判斷是否Iterator對象

      >>> from collections import Iterator
      >>> isinstance([], Iterator)
      # 不是迭代器
      >>> False
    
  4. 使用iter()函數(shù)變成迭代器Iterator

      # 使用內(nèi)置iter()函數(shù), list福稳、dict涎拉、str等Iterable變成Iterator
      >>> isinstance(iter([]), Iterator)
      >>> True
    
  5. 小結(jié):

    ~ 凡是可作用于for循環(huán)的對象都是Iterable類型;

    ~ 凡是可作用于next()函數(shù)的對象都是Iterator類型,它們表示一個惰性計(jì)算的序列曼库;

    ~ 集合數(shù)據(jù)類型如list区岗、dict略板、str等是Iterable但不是Iterator毁枯,不過可以通過iter()函數(shù)獲得一個Iterator對象。

    ~ for循環(huán)本質(zhì)上就是通過不斷調(diào)用next()函數(shù)實(shí)現(xiàn)的

      it = iter([1, 2, 3])
      while True:
        try:
          x = next(it)
          print(x)
        except StopIteration:
          print('done')
          break
    

函數(shù)式編程

  1. 由于python允許使用變量, 故而python不是純函數(shù)式(固定輸入固定輸出)編程語言

高階函數(shù)

  1. 函數(shù)名也是變量, 只是函數(shù)名已經(jīng)指定到函數(shù)

  2. 概念: 一個函數(shù)接受另外一個函數(shù)作為參數(shù), 高階函數(shù)

      >>> def add(x, y, f):
      ...  return f(x) + f(y)
      >>> add(-5, 1, abs)
      >>> 6
    

map/reducer

  1. map: 接受兩個參數(shù),函數(shù)Iterable, map將傳入的函數(shù)依次作用到序列的每個元素叮称,結(jié)果返回新的Iterator

      >>> def Fn(x):
      ...   return x * x
      # 第一個參數(shù)是函數(shù), 第二個參數(shù)是Iterable
      >>> map(Fn, [1, 2, 3])
      # 直接輸出的是map對象
      <map object at 0x000001B9AF26F4E0>
      # Iterator是惰性序列种玛,通過list()函數(shù)讓它把整個序列都計(jì)算出來并返回一個list
      >>> print(list(map(Fn, [1, 2, 3])))
      [1, 4, 9]
    
  2. reduce: 接受函數(shù)Iterable, 這個函數(shù)必須接收兩個參數(shù), reduce把結(jié)果繼續(xù)和序列的下一個元素做累積計(jì)算, 返回結(jié)果不是Iterator

    1. 效果就是: reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
      >>> from functools import reduce
      >>> def add(x, y):
      ...     return x * 10 + y
      ...
      >>> reduce(add, [1, 2, 3])
      123
    
  3. 自己實(shí)現(xiàn)原生的int函數(shù)

      from functools import reduce
      num = {'1': 1, '2': 2, '3'}
      def str2int(s):
        def fn(x, y):
          return x * 10 + y
        def char2num(x):
          return num[x]
        return reduce(fn, map(char2num, s))
      # 借用map和reduce, 此時(shí)輸入'123', 調(diào)用str2int函數(shù), 會轉(zhuǎn)化成數(shù)字123
    

filter

  1. 概念: 內(nèi)置高階函數(shù), 用于過濾序列, 返回Iterator

      def no_empty(s):
        return s and s.strip()
      l = filter(no_empty, ['a', '', None, 'B'])
      # 返回的是惰性序列, 使用list()獲得結(jié)果, 并返回list
      list(l)
    
  2. 埃氏篩法: 求解素?cái)?shù), 2素?cái)?shù), 2倍數(shù)刪除, 3素?cái)?shù), 3的倍數(shù)刪除, 一次下去, 求得所有素?cái)?shù)

sorted

  1. 概念: 內(nèi)置高階函數(shù), 對list進(jìn)行排序, 可以接收一個key函數(shù)來實(shí)現(xiàn)自定義的排序, 返回排序之后的list

      # 基本用法
      >>> sorted([10, -10, 2, 5])
      [-10, 2, 5, 10]
      # 作為高階函數(shù)用法, 按key作用后的結(jié)果排序
      sorted([5, -4, 3], key=abs)
      [3, -4, 5]
    
  2. 字符串排序, 按ASCII碼進(jìn)行排序

      # ascii碼里面, b > A
      >>> sorted(['bob', 'Amazing', 'Test'])
      ['Amazing', 'Test', 'bob']
      # 全部轉(zhuǎn)化為小寫再比較
      >>> sorted(['bob', 'Amazing', 'Test'], key=str.lower)
      ['Amazing', 'bob', 'Test']
    
  3. 反向排序, 可以傳入第三個參數(shù)reverse=True

返回函數(shù)

  1. 例子

      # 類似js閉包, 內(nèi)部函數(shù)可以得到外部函數(shù)的局部變量
      def lazy_sum(*num):
        def get_sum():
          sum = 0
          for key in num:
            sum = sum + key
          return sum
        return get_sum
      # 每次調(diào)用都是返回新的函數(shù)
      f = lazy_sum(1, 2, 3)
      # 再次調(diào)用才得出結(jié)果
      f()
    
  2. 閉包

返回閉包時(shí)牢記一點(diǎn):返回函數(shù)不要引用任何循環(huán)變量,或者后續(xù)會發(fā)生變化的變量瓤檐。

```py
  # 所引用的變量i全部變成了3
  def count():
    l = []
    for i in range(1, 4):
      def fn():
        return i * i
      l.append(fn)
    return l
  f1, f2, f3 = count()
  >>> f1()
  9
  >>> f2()
  9
  >>> f3()
  9
  # 改進(jìn)
  def count():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) # f(i)立刻被執(zhí)行赂韵,因此i的當(dāng)前值被傳入f()
    return fs
```

匿名函數(shù)

  1. 概念: 關(guān)鍵字lambda表示匿名函數(shù),冒號前面的x表示函數(shù)參數(shù), 只能有一個表達(dá)式, 表達(dá)式結(jié)果就是return的返回值

      >>> f = lambda x: x * x
      # 等價(jià)
      >>> def f(x):
      ...  return x * x
    

裝飾器(decorator)

  1. 概念: 在代碼運(yùn)行期間動態(tài)增加功能, 本質(zhì)上是返回函數(shù)的高階函數(shù)

  2. __name__屬性挠蛉,可以拿到函數(shù)的名字

      def fn(x):
        return x
      f = fn
      # 通過__name__拿到函數(shù)名字
      >>> fn.__name__
      'fn'
      >>> f.__name__
      'fn'
    
  3. 例子

      # 不帶參數(shù)的decorator
      import functools
    
      def log(func):
        # 為了最終返回的decorator的__name__指向的還是func而不會變成wrapper
        @functools.wraps(func)
        def wrapper(*args, **kw):
          print('call %s():' % func.__name__)
          return func(*args, **kw)
        return wrapper
    
      # 帶參數(shù)的decorator
      import functools
      # 帶參數(shù)的decorator, 在原來函數(shù)中可以做其他的操作
      def log(text):
        def decorator(func):
          @functools.wraps(func)
          def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
          return wrapper
        return decorator
      # 調(diào)用
      def fn(x):
        print('調(diào)用', x)
      fn = log('log日志')(fn)
      fn(88)
    

偏函數(shù)

  1. 概念: 偏函數(shù)是由functools模塊提供, functools.partial把一個函數(shù)的某些參數(shù)固定住(設(shè)置默認(rèn)值), 返回新的函數(shù)

      >>> import functools
      >>> int2 = functools.partial(int, base = 16)
      # 預(yù)設(shè)有10, 如果都不比是10大就選擇10
      >>> max2 = functools.partial(max, 10)
      >>> max2(1, 2, 3)
      10
    

模塊

  1. 概念: 一個.py文件一個模塊, 跨模塊不會出現(xiàn)變量名沖突

  2. 包: 為避免模塊名沖突, 每個包下面都有__init__.py文件

      # 引入模塊, myCompany是頂層包, a是a.py模塊, test是a.py的方法
      import myCompany.a
      myCompany.a.test()
    
  3. 自己創(chuàng)建模塊時(shí)要注意命名祭示,不能和Python自帶的模塊名稱沖突

[圖片上傳失敗...(image-f76f68-1547169230449)]

使用模塊

  1. 例子

      # 任何模塊代碼的第一個字符串都被視為模塊的文檔注釋;
      'my first module'
      # 代碼作者
      __author__ = 'bin.wang'
      import sys
      def test():
        args = sys.argv
        print(args)
        if len(args) == 1:
          print('hello world')
        elif len(args) == 2:
          print('hello, %s' % args[1])
        else:
          print('too many arguments')
      # 當(dāng)運(yùn)行到這個模塊時(shí), __name__會更改為__main__, 當(dāng)導(dǎo)入時(shí)判斷語句為False
      # 這是常見的運(yùn)行測試
      if __name__ == '__main__':
          test()
    
  2. 作用域

    1. 變量的命名規(guī)則
      模塊內(nèi)部使用: _XXX__XXX
      公開的函數(shù): XXX
      特殊變量: __XXX__, 直接引用但一般特殊用途, __name__

第三方模塊(類比js的npm)

  1. 安裝第三方模塊, 包管理工具pip

  2. 安裝pip

    1. win下安裝: 安裝python時(shí), 勾選pip和Add python.exe to Path(但我是勾選了Add Python 3.7 to PATH)

    2. mac系統(tǒng)下安裝: 記得使用pip3

    3. pip安裝第三方模塊: 一個一個安裝費(fèi)時(shí), 且需要考慮兼容性

  3. 安裝Anaconda(需要研究)

    1. 概念: 基于Python的數(shù)據(jù)處理和科學(xué)計(jì)算平臺, 內(nèi)置許多第三方庫, MySQL驅(qū)動程序谴古,Web框架Flask质涛,科學(xué)計(jì)算Numpy等. Anaconda會把系統(tǒng)Path中的python指向自己自帶的Python,并且掰担,Anaconda安裝的第三方模塊會安裝在Anaconda自己的路徑下汇陆,不影響系統(tǒng)已安裝的Python目錄

    2. 地址: https://www.anaconda.com/download/

面向?qū)ο缶幊?/h1>
  1. 概念: OOP, 設(shè)計(jì)思想, 封裝繼承和多態(tài)

類和實(shí)例

  1. 類和實(shí)例: 類實(shí)例化出對象, 對象之間方法一致, 數(shù)據(jù)不一樣

      # 關(guān)鍵字class, 類名大寫, object類, 代表該類是從object類繼承下來
      class Student(object):
        # 在創(chuàng)建實(shí)例時(shí)就把, name和score綁定上去, 類比jsconstruct
        # self代表實(shí)例本身(類比js的this), 創(chuàng)建實(shí)例就需要傳入name和score
        def __init__(self, name, score):
            # 加上__, 變成私有變量, 外部就不能訪問
            self.__name = name
            self.__score = score
        def print_score(self):
            print('%s: %s' % (self.__name, self.score))
      # 調(diào)用, 創(chuàng)建實(shí)例, 調(diào)用方法
      ben = Student('ben', 99)
      ben.print_score()
    

訪問限制

  1. 概念: 在屬性名稱前加上__, 變成私有變量, 這樣外部就不能訪問了(_XX還能訪問, 但也約定是私有變量), 注意區(qū)分__XXX__, 特殊變量, 能直接訪問

繼承和多態(tài)

```py
  class Animal(object):
    def run(self):
      print('animal is running')
  # 繼承, 子類方法覆蓋父類同類方法
  class Cat(Animal):
    def run(self):
      print('cat is running')
  # 實(shí)例化的對象跟str, list等一樣都屬于某個數(shù)據(jù)類型, 所以也能做類型判斷
  cat = Cat()
  isinstance(cat, Cat) # True
  isinstance([], list) # True
```

獲取對象信息(判斷對象類型)

  1. type()函數(shù): type(123) -> <class 'int'>

  2. isinstance()

  3. dir(): 獲得一個對象的所有屬性和方法, 返回一個包含字符串的list

      >>> dir(list)
      ['__add__', '__len__',..., 'copy']
      # 調(diào)用python內(nèi)置的len(list), 其實(shí)就是調(diào)用了__len__方法, 跟list.__len__() 是一樣的
    
  4. getattr(), hasattr(), setattr()

      class MyObject(object):
        def __init__(self):
            self.x = 9
        def power(self):
            return self.x * self.x
      obj = MyObject()
      hasattr(obj, 'x') # True
      hasattr(obj, 'power') # True
      setattr(obj, 'y', 2)
      hasattr(obj, 'y') # True
    

實(shí)例屬性和類屬性

  1. 給實(shí)例綁定屬性, 方法, 給類綁定屬性, 方法
      from types import MethodType
      # 定義類
      class Student(object):
        # 給類加屬性
        gender = '男'
        def __init__(self, name):
          self.name = name
      # 類綁定方法, 實(shí)例化的對象都可以使用
      def setScore(self, score):
        self.score = score
      Student.setScore = setScore
      # 實(shí)例化, 綁定的屬性可方法, 只適用于本實(shí)例
      s = Student('Ben')
      # 實(shí)例綁定屬性, 優(yōu)先級大于類
      s.gender = '女'
      def getAge(self, age):
        self.age = age
      s.getAge = MethodType(getAge, s)
      s.getAge(18)
      s.age       # 18, 且此實(shí)例不會影響別的實(shí)例
    

面向?qū)ο蟾呒壘幊?進(jìn)階版本)

使用slots

  1. 概念: 限制實(shí)例的屬性, 繼承它的子類不起作用, 但是子類設(shè)置了__slots__, 則會把父類的slots一起繼承

      class Student(object):
        # 用tuple的方式限定實(shí)例可增加的屬性
        __slots__ = ('name', 'age')
      s = Student()
      # AttributeError: 'Student' object has no attribute 'gender'
      s.gender = '男'
    

使用@property(不太理解)

  1. 概念: @property裝飾器, 把一個方法變成屬性調(diào)用的

      # score是可讀寫屬性, 那么是只讀屬性
      class Student(object):
        # property裝飾器, 方法變成屬性一樣使用
        @property
        def score(self):
          return self._score
        # score的設(shè)置, 像設(shè)置屬性一樣使用里面的方法
        @score.setter
        def score(self, val):
          self._score = val
        # 只設(shè)置了讀, 沒設(shè)置寫入, 就是只讀
        @property
        def name(self):
          return self._name
      # 實(shí)例
      s = Student()
      s.score = 60
      print(s.score)  # 60
    

多重繼承

  1. 概念: 多重繼承,一個子類就可以同時(shí)獲得多個父類的所有功能

      class Animal(object):
        pass
      class Runable(object):
        pass
      # 狗繼承了兩個父類
      class Dog(Animal, Runable):
        pass
    
  2. MixIn: 上述的繼承多個的設(shè)計(jì), 目的就是給一個類增加多個功能

定制類

  1. __str__: 使得輸出更易理解

      class Student(object):
        def __init__(self, name):
          self.name = name
        def __str__(self):
          return 'Student object (name: %s)' % (self.name)
        __repr__ = __str__
      # 原本: <__main__.Student object at 0x00000244C4994CF8>
      # 現(xiàn)在: Student object (name: test)
      print(Student('test'))
    
  2. __iter__: 使得類返回迭代對象, 使得類可迭代(不太理解作用)

      class Fib(object):
        def __init__(self):
          self.a, self.b = 0, 1
        def __iter__(self):
          return self
        def __next__(self):
          self.a, self.b = self.b , self.a + self.b
          # 退出循環(huán)條件
          if self.a > 10000:
            raise StopIteration
          return self.a
        for key in Fib():
          print(key)
    
  3. __getitem__: 使得類除了forin迭代之外, 還可以根據(jù)下標(biāo)取值

      class Fib(object):
        def __getitem__(self, n):
          a, b = 1, 1
          for x in range(n):
            a, b = b, a + b
          return a
      # 3, 能根據(jù)下標(biāo)取值
      print(Fib()[3])
    
  4. __getattr__

  5. __call__

枚舉類

  1. 概念: Enum可以把一組相關(guān)常量定義在一個class中带饱,且class不可變毡代,成員可以直接比較

      from enum import Enum, unique
      # value屬性則是自動賦給成員的int常量,默認(rèn)從1開始計(jì)數(shù)
      Month = Enum('Month', ('Jan', 'Feb'))
      # 如果value的屬性想自定義, 則需要用到@unique裝飾器
      @unique
      class Weekday(Enum):
        Sun = 0
        Mon = 1
      #訪問
      for name, member in Weekday.__members__.items():
        print(name, '=>', member, ',', member.value)
        # Sun => Weekday.Sun , 0
      # 根據(jù)value獲取值
      print(Weekday.Sun.value)  # 0
      # 根據(jù)value也可以反推member
      print(weekday(0))  # Sun
    

使用元類

  1. 概念

錯誤, 調(diào)試和測試

錯誤處理

try...except...finally...

  1. try某步報(bào)錯立馬跳轉(zhuǎn)到except, 最后finally都會執(zhí)行

      try:
      print('try...')
      r = 10 / int('2')
      print('result:', r)
      except ValueError as e:
        print('值錯誤:', e)
      except ZeroDivisionError as e:
        print('0做分母:', e)
      # try執(zhí)行不報(bào)錯的話, 才會執(zhí)行else
      else:
        print('no error!')
      finally:
        print('finally...')
      print('END')
    
  2. python 的錯誤也是class, 錯誤類型都繼承自BaseException, 且捕獲該類型錯誤, 還會順便捕獲其子類錯誤

  3. 常見的錯誤類型和繼承關(guān)系: https://docs.python.org/3/library/exceptions.html#exception-hierarchy

調(diào)用棧

  1. 概念: 分析錯誤的調(diào)用棧信息勺疼,才能定位錯誤的位置教寂。

記錄錯誤

  1. 概念: 內(nèi)置的logging模塊可以記錄錯誤信息

      import logging
      def foo(s):
        return 10 / int(s)
      def bar(s):
        return foo(s) * 2
      def main():
        # 直接通過logging捕獲錯誤, 但是不會退出程序的執(zhí)行, END還會執(zhí)行
        try:
          bar('0')
        except Exception as e:
          logging.exception(e)
      main()
      print('END')
    

拋出錯誤

  1. 概念

未完待續(xù)...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市执庐,隨后出現(xiàn)的幾起案子孝宗,更是在濱河造成了極大的恐慌,老刑警劉巖耕肩,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件因妇,死亡現(xiàn)場離奇詭異,居然都是意外死亡猿诸,警方通過查閱死者的電腦和手機(jī)婚被,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梳虽,“玉大人址芯,你說我怎么就攤上這事。” “怎么了谷炸?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵北专,是天一觀的道長。 經(jīng)常有香客問我旬陡,道長拓颓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任描孟,我火速辦了婚禮驶睦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘匿醒。我一直安慰自己场航,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布廉羔。 她就那樣靜靜地躺著溉痢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪憋他。 梳的紋絲不亂的頭發(fā)上孩饼,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天,我揣著相機(jī)與錄音举瑰,去河邊找鬼捣辆。 笑死,一個胖子當(dāng)著我的面吹牛此迅,可吹牛的內(nèi)容都是我干的汽畴。 我是一名探鬼主播,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼耸序,長吁一口氣:“原來是場噩夢啊……” “哼忍些!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起坎怪,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤罢坝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后搅窿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嘁酿,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年男应,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了闹司。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡沐飘,死狀恐怖游桩,靈堂內(nèi)的尸體忽然破棺而出牲迫,到底是詐尸還是另有隱情,我是刑警寧澤借卧,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布宏邮,位于F島的核電站垫挨,受9級特大地震影響崔梗,放射性物質(zhì)發(fā)生泄漏镰惦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一滨达、第九天 我趴在偏房一處隱蔽的房頂上張望奶稠。 院中可真熱鬧俯艰,春花似錦捡遍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至啦辐,卻和暖如春谓传,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背芹关。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工续挟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侥衬。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓诗祸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親轴总。 傳聞我的和親對象是個殘疾皇子直颅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評論 2 355

推薦閱讀更多精彩內(nèi)容