繆雪峰python筆記

  • 基礎(chǔ)

    1.r''表示''內(nèi)部的字符串默認(rèn)不轉(zhuǎn)義
    2.'''...'''表示多行內(nèi)容
    3. 布爾值:True、False(注意大小寫)
    4.與運(yùn)算and、或運(yùn)算:or、非運(yùn)算:not
    5. None代表空值
    6.聲明一個(gè)變量(前面不用聲明類型--動(dòng)態(tài)語(yǔ)言):  
             a = 1;//a是整數(shù)
             b = 'hello'//b是str(字符串)
    7.除法:
          /:  9/3 = 3.0(計(jì)算結(jié)果是浮點(diǎn)數(shù))
     地板除//:  10/3 = 3(計(jì)算結(jié)果是整數(shù))
    8.ord()函數(shù)獲取字符的整數(shù)表示,chr()函數(shù)把編碼轉(zhuǎn)換為對(duì)應(yīng)的字符
    9.對(duì)bytes類型的數(shù)據(jù)用帶b前綴的單引號(hào)或雙引號(hào)表示:x = b'ABC'
    10.要在網(wǎng)絡(luò)上傳輸,或者保存到磁盤上,就需要把str變?yōu)橐宰止?jié)為單位的bytes
        '中文'.encode('utf-8') 得到bytes類型為b'\xe4\xb8\xad\xe6\x96\x87'
      從網(wǎng)絡(luò)或磁盤上讀取了字節(jié)流,那么讀到的數(shù)據(jù)就是bytes。要把bytes變?yōu)閟tr,就需要用decode()
      b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')得到str類型為'中文'
    11.計(jì)算長(zhǎng)度len():計(jì)算的是str的字符數(shù),如果換成bytes應(yīng)該這么寫len(b'ABC')輸出3
         len('中文'.encode('utf-8'))輸出6,可見一個(gè)英文字符占一個(gè)字節(jié),一個(gè)中文字符占3個(gè)字節(jié)
    12.如果源代碼中有中文,則需要在開頭加上
          # -*- coding: utf-8 -*- 
      告訴Python解釋器按utf-8編碼讀取,注意:聲明了這個(gè)并不代表文件本身是utf-8編碼的
    13.格式化字符串%:
        'Hello, %s' % 'world' -----'Hello, world'
        'Hi, %s, you have $%d.' % ('Michael', 1000000)-----'Hi, Michael, you have $1000000.'
        格式化整數(shù)和浮點(diǎn)數(shù)還可以指定是否補(bǔ)0和整數(shù)與小數(shù)的位數(shù):
        '%2d-%02d' % (3, 1)----' 3-01'
        '%.2f' % 3.1415926-----'3.14'
        %015d  ----至少15位(不足高位補(bǔ)0)
        如果你不太確定應(yīng)該用什么,%s永遠(yuǎn)起作用,它會(huì)把任何數(shù)據(jù)類型轉(zhuǎn)換為字符串:
        'Age: %s. Gender: %s' % (25, True)----'Age: 25. Gender: True'
        字符串里面的%是一個(gè)普通字符怎么辦?這個(gè)時(shí)候就需要轉(zhuǎn)義,用%%來表示一個(gè)%
    14.有序列表list(可變)和tuple(不可變)
            list:
                  s = ['first','second','three']//索引從0開始s[0]
                  //還可以-1做索引代表最后一個(gè)s[-1]是three、s[-2]、s[-3]
                  s.append('x')
                  s.insert(1,'x')
                  s.pop()//刪除末尾元素
                  s.pop(1)//刪除index為1的元素
                  s[1]='haha'//替換
                  list里面的元素的數(shù)據(jù)類型也可以不同,比如:
                  L = ['Apple', 123, True]
                  [] 是空列表
           tuple:
                 ()是空tuple
                 (1)定義的不是tuple而是小括號(hào)1這個(gè)數(shù)
                所以,只有1個(gè)元素的tuple定義時(shí)必須加一個(gè)逗號(hào),,來消除歧義:(1,)
                “可變的”tuple:
                t = ('a', 'b', ['A', 'B'])
                t[2][0] = 'X'
                t[2][1] = 'Y'
    15.條件判斷:
                    if x://只要x是非零數(shù)值、非空字符串、非空l(shuí)ist等,就判斷為True,否則為False
                        print('True')//注意要縮進(jìn)
    16.int()函數(shù)把str轉(zhuǎn)換成整數(shù)
    17.循環(huán)有兩種:a.for...in循環(huán) b.while循環(huán)
          names = ['Michael', 'Bob', 'Tracy']
          for name in names:
              print(name)
          sum = 0
          n = 99
          while n > 0:
              sum = sum + n
              n = n - 2
          print(sum)
    18. 字典dict,在其他語(yǔ)言中也稱為map,使用鍵-值(key-value)存儲(chǔ),具有極快的查找速度
          d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
          d['Michael']//得到 95
          避免key不存在的錯(cuò)誤,有兩種辦法,
            一是通過in判斷key是否存在:'Thomas' in d
            二是通過dict提供的get方法,如果key不存在,可以返回None,或者自己指定的value:
              d.get('Thomas')  
              d.get('Thomas', -1)
          pop(key)//刪除
          dict的key必須是不可變對(duì)象
    19. set(無序和無重復(fù)元素的集合):set和dict類似,也是一組key的集合,但不存儲(chǔ)value。由于key不能重復(fù),所以,在set中,沒有重復(fù)的key
        s = set([1, 2, 3])//傳入的參數(shù)[1, 2, 3]是一個(gè)list
        add(key)
        remove(key)
    20.字符串可以通過+相連(和java一樣)
    21.bin()十進(jìn)制轉(zhuǎn)二進(jìn)制,hex()十進(jìn)制轉(zhuǎn)十六進(jìn)制,oct()十進(jìn)制轉(zhuǎn)八進(jìn)制,0b二進(jìn)制  0x十六進(jìn)制  0八進(jìn)制
    22.join()方法:
      fields = []
      fields.append('a')
      fields.append('b')
      fields.append('c')
      fields.append('d')
      print(" ".join(fields))#輸出a b c d
      print(",".join(fields))#輸出a,b,c,d
    
  • 函數(shù)

    1.函數(shù)名是指向一個(gè)函數(shù)對(duì)象的引用,可以把函數(shù)名賦給一個(gè)變量,相當(dāng)于“別名”  eg:
      a = abs #abs是內(nèi)置函數(shù)取絕對(duì)值
      a(-1)
    2.定義函數(shù):
          def my_abs(x): #有冒號(hào)
              if x >= 0: #注意縮進(jìn)
                  return x #注意縮進(jìn)
              else:
                  return -x
    3.默認(rèn)參數(shù):
        def power(x, n=2):
        power(5)和power(5,2)的結(jié)果是一樣的
       默認(rèn)參數(shù)的坑:L默認(rèn)是一個(gè)空列表,每次調(diào)用這個(gè)方法L的內(nèi)容會(huì)改變,導(dǎo)致L的內(nèi)容是改變后的內(nèi)容
        def add_end(L=[]):
            L.append('END')
            return L  
        調(diào)用第一次返回['END']
        調(diào)用第二次返回['END','END']
        ...
        解決方法:
        def add_end(L=None):
            if L is None:
                L = []
            L.append('END')
            return L
        因?yàn)镹one是不可變對(duì)象,所以每次調(diào)用只會(huì)加一個(gè)
        調(diào)用第一次返回['END']
        調(diào)用第二次返回['END']
    4.可變參數(shù)(*):在函數(shù)調(diào)用時(shí)自動(dòng)組裝為一個(gè)tuple
        def calc(*numbers):
        calc(1,2,3) #調(diào)用
        如果已經(jīng)有了一個(gè)list或tuple,只需要在前面加*就會(huì)當(dāng)成可變參數(shù)
        nums = [1, 2, 3]
        calc(*nums)
    5.關(guān)鍵字參數(shù)(**):可變參數(shù)在函數(shù)調(diào)用時(shí)自動(dòng)組裝為一個(gè)dict,是參數(shù)的拷貝,改變不會(huì)影響參數(shù)本身
      def person(name, age, **kw):
          print('name:', name, 'age:', age, 'other:', kw)
      eg:person('Adam', 45, gender='M', job='Engineer')
            輸出name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
      如果已經(jīng)有了一個(gè)dict,只需要在前面加**就會(huì)當(dāng)成關(guān)鍵字參數(shù)
      extra = {'city': 'Beijing', 'job': 'Engineer'}
      person('Jack', 24, **extra)
    6.命名關(guān)鍵字參數(shù)
      對(duì)于關(guān)鍵字參數(shù),函數(shù)的調(diào)用者可以傳入任意不受限制的關(guān)鍵字參數(shù)
      如果要限制關(guān)鍵字參數(shù)的名字,就可以用命名關(guān)鍵字參數(shù)
      例如,只接收city和job作為關(guān)鍵字參數(shù),定義如下:
      def person(name, age, *, city, job): #*后面的參數(shù)被視為命名關(guān)鍵字參數(shù)
          print(name, age, city, job) 
      此時(shí)調(diào)用函數(shù)時(shí)必須傳遞四個(gè)參數(shù),并且最后兩個(gè)字典的key必須分別是 city和job,否則會(huì)報(bào)錯(cuò)
      如果函數(shù)定義中已經(jīng)有了一個(gè)可變參數(shù),后面跟著的命名關(guān)鍵字參數(shù)就不再需要一個(gè)特殊分隔符*了:
      def person(name, age, *args, city, job):
          print(name, age, args, city, job)
      命名關(guān)鍵字可以有缺省值:
      def person(name, age, *, city='Beijing', job): #調(diào)用時(shí)可以不用傳city的字典
    7.參數(shù)組合
      def f1(a, b, c=0, *args, **kw):
            print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
      注意 tuple 和 list可以調(diào)用  eg:
         args = (1, 2, 3, 4)
         kw = {'d': 99, 'x': '#'}
         f1(*args, **kw)
        輸出a = 1 b = 2 c = 3 args = (4,) kw = {'d': 99, 'x': '#'}
    8.尾遞歸
        在函數(shù)返回的時(shí)候,調(diào)用自身本身,并且,return語(yǔ)句不能包含表達(dá)式。這樣,編譯器或者解釋器就可以把尾遞歸做優(yōu)化,使遞歸本身無論調(diào)用多少次,都只占用一個(gè)棧幀,不會(huì)出現(xiàn)棧溢出的情況
        普通遞歸:
          def fact(n):
              if n==1:
                  return 1
              return n * fact(n - 1)#表達(dá)式
          尾遞歸:
          def fact(n):
              return fact_iter(n, 1)
          
          def fact_iter(num, product):
              if num == 1:
                  return product
              return fact_iter(num - 1, num * product) #沒有表達(dá)式,僅返回遞歸函數(shù)本身
    
  • 高級(jí)特性

    1. 切片(Slice):取一個(gè)list或tuple的部分元素
        L[0:3]代表取L的[0,3),如果第一個(gè)索引為0,還可以省略:L[:3]
        L[1:len(L)]代表L的[1,L的長(zhǎng)度),可以省略為L(zhǎng)[1:]
        L[-1]取倒數(shù)第一個(gè)元素,L[-2:]代表取后面兩個(gè)
        L[:10:2] 前10個(gè)元素 每隔兩個(gè)取一個(gè)
        L[::5] 所有元素,每隔五個(gè)取一個(gè)
        對(duì)tuple切片得到的結(jié)果還是tuple
        字符串'xxx'也可以看成是一種list,可以進(jìn)行切片(類似java中的substring),eg:
        'ABCDEFG'[:3] ->'ABC'
    2.迭代(for ... in):只要是可迭代對(duì)象就可以使用這種方式
        dict默認(rèn)是對(duì)key迭代,若要對(duì)value 則 for value in dict.values():  若同時(shí)對(duì)key value迭代則for k, v in d.items()
        字符串也是可迭代對(duì)象 eg:for ch in 'ABC':
        如何判斷一個(gè)對(duì)象是可迭代對(duì)象呢?方法是通過collections模塊的Iterable類型判斷:
          from collections import Iterable
          isinstance('abc', Iterable) # str是否可迭代 輸出true
        對(duì)list實(shí)現(xiàn)類似Java那樣的下標(biāo)循環(huán):
          for i, value in enumerate(['A', 'B', 'C']):
              print(i, value) #輸出0 A   (","逗號(hào)會(huì)輸出空格)
                                  1 B
                                  2 C
       同時(shí)遍歷兩個(gè)變量
       for x, y in [[1, 1], [2, 4], [3, 9]]:
            print(x, y)
    3.列表生成式(#注意操作在for前面)
        list(range(1, 11)) 生成 [1,10]
        [x * x for x in range(1, 11)] 生成[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
        還可以過濾:
        [x * x for x in range(1, 11) if x % 2 == 0] 生成[4, 16, 36, 64, 100]
        兩層循環(huán),可以生成全排列:
        [m + n for m in 'ABC' for n in 'XYZ']生成 ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
        for循環(huán)其實(shí)可以同時(shí)使用兩個(gè)甚至多個(gè)變量:
        d = {'x': 'A', 'y': 'B', 'z': 'C' }
        for k, v in d.items():
            print(k, '=', v)
        輸出:y = B
             x = A
             z = C
        把一個(gè)list中所有的字符串變成小寫:
        L = ['Hello', 'World', 'IBM', 'Apple']
        [s.lower() for s in L] #注意操作在for前面
      4.生成器(generator):不必創(chuàng)建完整的list,從而節(jié)省大量的空間
        把一個(gè)列表生成式的[]改成(),就創(chuàng)建了一個(gè)generator
        如果一個(gè)函數(shù)定義中包含yield關(guān)鍵字,那么這個(gè)函數(shù)就不再是一個(gè)普通函數(shù),而是一個(gè)generator
        每次調(diào)用next()的時(shí)候執(zhí)行,遇到y(tǒng)ield語(yǔ)句返回,再次執(zhí)行時(shí)從上次返回的yield語(yǔ)句處繼續(xù)執(zhí)行,eg定義一個(gè)generator,依次返回?cái)?shù)字1,3,5:
        def odd():
        yield 1
        yield(3)
        yield(5)
        for i in odd():
        print(i)
        輸出1 3 5
      也可以這樣  o = odd()
                next(o)
                next(o)
                next(o)
       同樣輸出1 3 5(到了最后一個(gè)元素,再調(diào)用next(o)會(huì)報(bào)錯(cuò))
    5.迭代器(Iterator)
        凡是可作用于for循環(huán)的對(duì)象都是Iterable類型;
        凡是可作用于next()函數(shù)的對(duì)象都是Iterator類型,它們表示一個(gè)惰性計(jì)算的序列;
        集合數(shù)據(jù)類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數(shù)獲得一個(gè)Iterator對(duì)象。
        Python的for循環(huán)本質(zhì)上就是通過不斷調(diào)用next()函數(shù)實(shí)現(xiàn)的
    
  • 函數(shù)式編程

    1.map()函數(shù)接收兩個(gè)參數(shù),一個(gè)是函數(shù),一個(gè)是Iterable,map將傳入的函數(shù)依次作用到序列的每個(gè)元素,并把結(jié)果作為新的Iterator返回
    2. reduce()和map接收參數(shù)一樣,把結(jié)果繼續(xù)和序列的下一個(gè)元素做累積計(jì)算eg:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
    3.字符串轉(zhuǎn)int(利用 map 和reduce)
        from functools import reduce
        def str2int(s):
            def fn(x, y):
                return x * 10 + y
            def char2num(s):
                return {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}[s]
            return reduce(fn, map(char2num, s))
    4.filter()篩選和map接收參數(shù)一樣,返回也是Iterator惰性序列
    5.sorted()函數(shù)可以對(duì)list進(jìn)行排序,還可以接收一個(gè)參數(shù)key函數(shù)來實(shí)現(xiàn)自定義排序eg:按絕對(duì)值排序:
      sorted([36, 5, -12, 9, -21], key=abs) # 輸出 [5, 9, -12, -21, 36]
      要進(jìn)行反向排序,不必改動(dòng)key函數(shù),可以傳入第三個(gè)參數(shù)reverse=True
    6.返回一個(gè)函數(shù)時(shí),牢記該函數(shù)并未執(zhí)行,返回函數(shù)中不要引用任何可能會(huì)變化的變量
      def count():
          fs = []
          for i in range(1, 4):
              def f():
                   return i*i
              fs.append(f)
          return fs
      
      f1, f2, f3 = count() #此時(shí)f1() f2() f3()的結(jié)果都是9,因?yàn)橐昧送粋€(gè)變量i ,解決辦法:
      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       
    7.匿名函數(shù)
      def f(x):
          return x * x
      等價(jià)于 lambda x: x * x
    8.裝飾器:在不改變某個(gè)函數(shù)具體實(shí)現(xiàn)的情況下,增加函數(shù)的功能
      def now():
          print('2015-3-25')
      需要增加打印函數(shù)名的功能:
      def log(func):
          @functools.wraps(func)#用于把原始函數(shù)的__name__等屬性復(fù)制到wrapper()函數(shù)中,否則調(diào)用now.__name__會(huì)得到 wrapper
          def wrapper(*args, **kw):
              print('call %s():' % func.__name__)#__name__是函數(shù)對(duì)象內(nèi)置
              return func(*args, **kw)
          return wrapper
      使用@
      @log
      def now():
          print('2015-3-25')
     @log 等價(jià)于 now = log(now)
      輸出:call now():
           2015-3-25
    如果decorator本身需要傳入?yún)?shù),那就需要編寫一個(gè)返回decorator的高階函數(shù)eg:
      def log(text):
          def decorator(func):
              def wrapper(*args, **kw):
                  print('%s %s():' % (text, func.__name__))
                  return func(*args, **kw)
              return wrapper
          return decorator
      用法:
      @log('execute')
      def now():
          print('2015-3-25')
    9.偏函數(shù)(functools.partial):把一個(gè)函數(shù)的某些參數(shù)給固定住(也就是設(shè)置默認(rèn)值),返回一個(gè)新的函數(shù),調(diào)用這個(gè)新函數(shù)會(huì)更簡(jiǎn)單
       int()函數(shù)默認(rèn)按十進(jìn)制轉(zhuǎn)換
      int('12345', 8)轉(zhuǎn)化8進(jìn)制到十進(jìn)制
      import functools
      int2 = functools.partial(int, base=2)#偏函數(shù),轉(zhuǎn)換二進(jìn)制到10進(jìn)制
      int2('1000000')  相當(dāng)于kw = { 'base': 2 }
                            int('10010', **kw)
      max2 = functools.partial(max, 10)#實(shí)際上會(huì)把10作為*args的一部分自動(dòng)加到左邊,也就是:
      max2(5, 6, 7)相當(dāng)于args = (10, 5, 6, 7)
                        max(*args)
    
  • 模塊

    1.一個(gè).py文件就是一個(gè)模塊
    2.if __name__=='__main__':  #運(yùn)行本模塊會(huì)為True,在其他模塊導(dǎo)入這個(gè)模塊時(shí)會(huì)為False
    3.作用域:
          正常的函數(shù)和變量名是公開的(public)eg:a、b、c
          類似_xxx和__xxx這樣的函數(shù)或變量就是非公開的(private)eg:_a、__b
    
  • 面向?qū)ο缶幊?/p>

    1.類(class)和實(shí)例:
      class Student(object):#表示Student類繼承object
          def __init__(self, name, score):#第一個(gè)參數(shù)必須是self,init前后有兩個(gè)下劃線,代表初始化必須傳name、score兩個(gè)參數(shù)
              self.name = name#public 
              self.__score = score#private
        不能直接訪問__score是因?yàn)镻ython解釋器對(duì)外把__score變量改成了_Student__score,所以,仍然可以通過_Student__score來訪問__score變量(不建議!!)
        bart.__score = 20 # 設(shè)置__score變量!是給bart新增了一個(gè)變量__score
    2.type()獲取對(duì)象的類型
    3.類屬性(類似java的靜態(tài)變量)
      class Student(object):
          name = 'Student'
    4.在類中定義的函數(shù)第一個(gè)參數(shù)永遠(yuǎn)是實(shí)例變量self(self指向創(chuàng)建的實(shí)例本身),并且調(diào)用時(shí)不用傳遞該參數(shù)
    5.__init__類似于構(gòu)造方法,用于創(chuàng)建類時(shí)必須傳遞的參數(shù)
    6.變量名類似__xxx__的是特殊變量,特殊變量是可以直接訪問的,不是private變量
      7.dir()獲得一個(gè)對(duì)象的所有屬性和方法
      8.類似__xxx__的屬性和方法在Python中都是有特殊用途的,調(diào)用len()函數(shù)試圖獲取一個(gè)對(duì)象的長(zhǎng)度,實(shí)際上,在len()函數(shù)內(nèi)部,它自動(dòng)去調(diào)用該對(duì)象的__len__() eg:
          len('ABC') == 'ABC'.__len__()
      我們自己寫的類,如果也想用len(myObj)的話,就自己寫一個(gè)__len__()方法
    9.給實(shí)例綁定屬性的方法是通過實(shí)例變量,或者通過self變量
    10.給類動(dòng)態(tài)綁定方法:
      def set_age(self, age): # 定義一個(gè)函數(shù)作為實(shí)例方法
          self.age = age
      from types import MethodType
      s.set_age = MethodType(set_age, s) # 給實(shí)例綁定一個(gè)方法
      s.set_age(25) # 調(diào)用實(shí)例方法
      s.age # 測(cè)試結(jié)果 輸出25
        但是,給一個(gè)實(shí)例綁定的方法,對(duì)另一個(gè)實(shí)例是不起作用的,解決方法給class綁定:
            def set_score(self, score):
                self.score = score
            Student.set_score = set_score
    
  • 面向?qū)ο蟾呒?jí)編程

    1.動(dòng)態(tài)綁定允許我們?cè)诔绦蜻\(yùn)行的過程中動(dòng)態(tài)給class加上功能:
    def set_score(self, score):
         self.score = score
    Student.set_score = set_score #動(dòng)態(tài)綁定方法
    s = Student()
    s.set_score(100)
    s.score 
    2.__slots__限制實(shí)例可綁定的屬性(僅對(duì)當(dāng)前類實(shí)例起作用,對(duì)繼承的子類不起作用)
      class Student(object):
          __slots__ = ('name', 'age') # 用tuple定義允許綁定的屬性名稱
       s = Student() # 創(chuàng)建新的實(shí)例
        s.name = 'Michael' # 綁定屬性'name'
        s.age = 25 # 綁定屬性'age'
        s.score = 99 # 綁定屬性'score'會(huì)報(bào)錯(cuò)
    3.多繼承 class Dog(Mammal, Runnable):
    4.__str__ 類似java 的toString方法
      class Student(object):
          def __init__(self, name):
          self.name = name
          def __str__(self):
          return 'Student object (name: %s)' % self.name
          使用:print(Student('Michael')) 輸出 Student object (name: Michael)
        直接顯示變量調(diào)用的不是__str__(),而是__repr__()(可以令__repr__ = __str__)
    5.__iter__ 使一個(gè)類可用于for ... in循環(huán)
      class Fib(object):
          def __init__(self):
              self.a, self.b = 0, 1 # 初始化兩個(gè)計(jì)數(shù)器a,b
          def __iter__(self):
              return self # 實(shí)例本身就是迭代對(duì)象,故返回自己
          def __next__(self):
              self.a, self.b = self.b, self.a + self.b # 計(jì)算下一個(gè)值
              if self.a > 100000: # 退出循環(huán)的條件
                  raise StopIteration()
              return self.a # 返回下一個(gè)值
    6.__getitem__使一個(gè)類可按照下標(biāo)取出元素
    7.__getattr__使可以訪問一個(gè)非類的屬性
      class Student(object):
          def __init__(self):
              self.name = 'Michael'
          def __getattr__(self, attr):
              if attr=='score':
                  return 99
              Student().score
       實(shí)例:鏈?zhǔn)秸{(diào)用
      class Chain(object):
          def __init__(self, path=''):
              self._path = path
          def __getattr__(self, path):
              return Chain('%s/%s' % (self._path, path))
          def __str__(self):
              return self._path
          __repr__ = __str__
            Chain().status.user.timeline.list #輸出:'/status/user/timeline/list'
    8.__call__ 使得對(duì)象方便的調(diào)用方法
      class Student(object):
          def __init__(self, name):
              self.name = name
          def __call__(self):
              print('My name is %s.' % self.name)
    調(diào)用:s = Student('neo')
         s() #輸出My name is neo
    所以你完全可以把對(duì)象看成函數(shù),把函數(shù)看成對(duì)象
    通過callable()函數(shù),我們就可以判斷一個(gè)對(duì)象是否是“可調(diào)用”對(duì)象.
    9.枚舉
    from enum import Enum
    Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
    直接使用Month.Jan來引用一個(gè)常量,枚舉它的所有成員:
      for name, member in Month.__members__.items():
          print(name, '=>', member, ',', member.value)
    10.type()函數(shù)既可以返回一個(gè)對(duì)象的類型,又可以創(chuàng)建出新的類型
          返回類型:
      from hello import Hello
      h = Hello()
      h.hello()#Hello, world.
      print(type(Hello))#<class 'type'> Hello是一個(gè)class,它的類型就是type
      print(type(h))#<class 'hello.Hello'> h是一個(gè)實(shí)例,它的類型就是hello.py模塊下的 Hello類
          創(chuàng)建類型:
      def fn(self, name='world'): # 先定義函數(shù)
          print('Hello, %s.' % name)
          Hello = type('Hello', (object,), dict(hello=fn)) # 創(chuàng)建Hello class
          h = Hello()
          h.hello()#Hello, world.
          print(type(Hello))#<class 'type'>
          print(type(h))#<class '__main__.Hello'> # __main__模塊的Hello類
        type()函數(shù)參數(shù):
                1.class的名稱;
                2.繼承的父類集合,注意Python支持多重繼承,如果只有一個(gè)父類,別忘了tuple的單元素寫法;
                3.class的方法名稱與函數(shù)綁定,這里我們把函數(shù)fn綁定到方法名hello上。
    11.元類metaclass(可以把類看成是metaclass創(chuàng)建出來的“實(shí)例”)
      # metaclass是類的模板,所以必須從`type`類型派生:
      class ListMetaclass(type):
          def __new__(cls, name, bases, attrs):
              attrs['add'] = lambda self, value: self.append(value)
              return type.__new__(cls, name, bases, attrs)
      class MyList(list, metaclass=ListMetaclass):#說明Python創(chuàng)建MyList會(huì)去調(diào)用元類ListMetaclass的__new__方法
          pass
      L = MyList()
      L.add(1)
      print(L)#輸出[1]
    __new__()方法接收到的參數(shù)依次是:
      1.當(dāng)前準(zhǔn)備創(chuàng)建的類的對(duì)象;
      2.類的名字;
      3.類繼承的父類集合;
      4.類的方法集合。
    12.使用@property:@property裝飾器就是負(fù)責(zé)把一個(gè)方法變成屬性調(diào)用。
      class Student(object):
          @property
          def birth(self):
              return self._birth#下劃線開頭的變量名是可以外部直接方法的(但是不建議這么做)
          @birth.setter #@property內(nèi)部創(chuàng)建的:方法名.setter
          def birth(self, value):
              self._birth = value
          @property
          def age(self):
              return 2015 - self._birth
        birth是可讀寫屬性,而age就是一個(gè)只讀屬性
        s = Student()
        s.birth = 12#等同于s.birth(12)   .方法名
        s.birth #等同于s.birth()
    13.python可以多繼承
    
  • 錯(cuò)誤、調(diào)試、測(cè)試

    1.
      try:
          print('try...')
          r = 10 / int('2')
          print('result:', r)
      except ValueError as e:
          print('ValueError:', e)
      except ZeroDivisionError as e:
          print('ZeroDivisionError:', e)
      else:
          print('no error!')
      finally:
          print('finally...')
    2. raise類似java的throw
        logging類似Log
    3. pdb命令行方式進(jìn)行調(diào)試
    
  • IO編程

    1.文本文件(默認(rèn)utf-8)
      try:
          f = open('/Users/neo/fps.txt', 'r',encoding='gbk')#'r'表示讀
          print(f.read())
      finally:
          if f:
              f.close()#及時(shí)關(guān)閉
    等價(jià)于
      with open('/Users/neo/fps.txt', 'r') as f:
          print(f.read())#不用close
      read()一次性讀取全部?jī)?nèi)部到內(nèi)存有危險(xiǎn),可反復(fù)調(diào)用read(size)方法
    2.二進(jìn)制文件
      f = open('/Users/michael/test.jpg', 'rb')
    3. StringIO:在內(nèi)存中讀寫str
      from io import StringIO
      f = StringIO()
      f.write('hello')
      f.write(' ')
      f.write('world!')
      print(f.getvalue())#輸出hello world!
    
      from io import StringIO
      f = StringIO('Hello!\nHi!\nGoodbye!')
      while True:
          s = f.readline()
          if s == '':
              break
          print(s.strip())#輸出Hello!
                              Hi!
                              Goodbye!
    4.BytesIO:用法和StringIO類似,是內(nèi)存中讀寫字節(jié)
    5.import os
      os.path.abspath('.')# 查看當(dāng)前目錄的絕對(duì)路徑:
      os.path.join('/Users/neo', 'testdir')# 在某個(gè)目錄下創(chuàng)建一個(gè)新目錄,首先把新目錄的完整路徑表示出來:
      os.mkdir('/Users/neo/testdir')# 然后創(chuàng)建一個(gè)目錄:
      os.rmdir('/Users/neo/testdir')# 刪掉一個(gè)目錄:
      os.rename('test.txt', 'test.py')# 對(duì)文件重命名:
      os.remove('test.py')# 刪掉文件:
    5.列出所有的.py文件
      [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
    6. pickling序列化(利用pickle模塊)
        對(duì)象到JSON格式的轉(zhuǎn)換(json模塊)
      import json
      d = dict(name='Bob', age=20, score=88)
      print(json.dumps(d))#輸出{"name": "Bob", "age": 20, "score": 88}
        JSON轉(zhuǎn)為對(duì)象
      import json
      json_str = '{"age": 20, "score": 88, "name": "Bob"}'
      persion = json.loads(json_str)
      print(persion['age'])#輸出20
    7.json模塊序列化類
      import json
      class Student(object):
          def __init__(self, name, age, score):
              self.name = name
              self.age = age
              self.score = score
      def student2dict(std):
              return {
                  'name': std.name,
                  'age': std.age,
                  'score': std.score}
    
      s = Student('Bob', 20, 88)
      print(json.dumps(s,default=student2dict))
      print(json.dumps(s, default=lambda obj: obj.__dict__))#把任意class的實(shí)例變?yōu)閐ict
    反序列化:
      import json
      class Student(object):
          def __init__(self, name, age, score):
              self.name = name
              self.age = age
              self.score = score
      def dict2student(d):
          return Student(d['name'], d['age'], d['score'])
      json_str = '{"age": 20, "score": 88, "name": "Bob"}'
      print(json.loads(json_str, object_hook=dict2student))
    
  • 進(jìn)程和線程

    1.Unix/Linux操作系統(tǒng)提供了一個(gè)fork()系統(tǒng)調(diào)用,它非常特殊。普通的函數(shù)調(diào)用,調(diào)用一次,返回一次,
      但是fork()調(diào)用一次,返回兩次,因?yàn)椴僮飨到y(tǒng)自動(dòng)把當(dāng)前進(jìn)程(稱為父進(jìn)程)復(fù)制了一份(稱為子進(jìn)程),然后,分別在父進(jìn)程(返回子進(jìn)程id)和子進(jìn)程(返回0)內(nèi)返回
      import os
      print('Process (%s) start...' % os.getpid())
      # Only works on Unix/Linux/Mac:
      pid = os.fork()
      if pid == 0:
          print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
      else:
          print('I (%s) just created a child process (%s).' % (os.getpid(), pid))
     輸出Process (1812) start...
        I (1812) just created a child process (1813).
        I am child process (1813) and my parent is 1812.
    2.Windows沒有fork,可使用multiprocessing模塊
      from multiprocessing import Process
      import os
      # 子進(jìn)程要執(zhí)行的代碼
      def run_proc(name):
          print('Run child process %s (%s)...' % (name, os.getpid()))
      if __name__=='__main__':
          print('Parent process %s.' % os.getpid())
          p = Process(target=run_proc, args=('test',))
          print('Child process will start.')
          p.start()
          p.join()#等待子進(jìn)程結(jié)束后再繼續(xù)往下運(yùn)行
          print('Child process end.')
    3.多線程(使用threading模塊)
      import time, threading
      # 新線程執(zhí)行的代碼:
      def loop():
          print('thread %s is running...' % threading.current_thread().name)
          n = 0
          while n < 5:
              n = n + 1
              print('thread %s >>> %s' % (threading.current_thread().name, n))
              time.sleep(1)
          print('thread %s ended.' % threading.current_thread().name)
      
      print('thread %s is running...' % threading.current_thread().name)
      t = threading.Thread(target=loop, name='LoopThread')
      t.start()
      t.join()#主線程等待子線程執(zhí)行完畢
      print('thread %s ended.' % threading.current_thread().name)
    
    4.鎖:lock = threading.Lock()
           lock.acquire()#獲取鎖
          lock.release()#一定要手動(dòng)釋放鎖
    5.Python解釋器由于設(shè)計(jì)時(shí)有GIL全局鎖,任何Python線程執(zhí)行前,必須先獲得GIL鎖,然后,每執(zhí)行100條字節(jié)碼,
      解釋器就自動(dòng)釋放GIL鎖,讓別的線程有機(jī)會(huì)執(zhí)行,導(dǎo)致了多線程無法利用多核(可以使用多進(jìn)程)
    6. ThreadLocal
      import threading
      # 創(chuàng)建全局ThreadLocal對(duì)象:
      local_school = threading.local()
      def process_student():
          # 獲取當(dāng)前線程關(guān)聯(lián)的student:
          std = local_school.student
          print('Hello, %s (in %s)' % (std, threading.current_thread().name))
      def process_thread(name):
          # 綁定ThreadLocal的student:
          local_school.student = name
          process_student()
      t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A')
      t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')
      t1.start()
      t2.start()
      t1.join()
      t2.join()
    輸出Hello, Alice (in Thread-A)
       Hello, Bob (in Thread-B)
    
  • 正則表達(dá)式

    1. \d:匹配一個(gè)數(shù)字
       \w:匹配一個(gè)字母或數(shù)字
       \s:匹配一個(gè)空格(也包括Tab等空白符)
    2.匹配變長(zhǎng)的字符:
      *表示任意個(gè)字符(包括0個(gè))
      +表示至少一個(gè)字符
      ?表示0個(gè)或1個(gè)字符
      {n}表示n個(gè)字符,用{n,m}表示n-m個(gè)字符
    3.需要轉(zhuǎn)義的字符:
      _ :\_
    4.表示范圍:[]
        [0-9a-zA-Z\_]可以匹配一個(gè)數(shù)字、字母或者下劃線
        [0-9a-zA-Z\_]+可以匹配至少由一個(gè)數(shù)字、字母或者下劃線組成的字符串,比如'1','a100','0_Z','Py3000'等等
    5.^表示行的開頭,^\d表示必須以數(shù)字開頭。
      $表示行的結(jié)束,\d$表示必須以數(shù)字結(jié)束。
    6.re模塊
    判斷是否匹配:   
      import re
      if re.match(r'^\d{3}\-\d{3,8}$', '010-12345'):
          print('yes')
      else:
          print('no')
        輸出yes
    ?切分字符串:
    
  • 網(wǎng)絡(luò)編程

    1.網(wǎng)絡(luò)通信其實(shí)就是兩個(gè)進(jìn)程通信
    2.如果一臺(tái)計(jì)算機(jī)同時(shí)接入到兩個(gè)或更多的網(wǎng)絡(luò),比如路由器,它就會(huì)有兩個(gè)或多個(gè)IP地址,所以,IP地址對(duì)應(yīng)的實(shí)際上是計(jì)算機(jī)的網(wǎng)絡(luò)接口,通常是網(wǎng)卡
    3.IP地址實(shí)際上是一個(gè)32位整數(shù)(稱為IPv4),以字符串表示的IP地址如192.168.0.1實(shí)際上是把32位整數(shù)按8位分組后的數(shù)字表示,目的是便于閱讀
    4.IPv6地址實(shí)際上是一個(gè)128位整數(shù)
    5.IP協(xié)議負(fù)責(zé)把數(shù)據(jù)從一臺(tái)計(jì)算機(jī)通過網(wǎng)絡(luò)發(fā)送到另一臺(tái)計(jì)算機(jī)
    6.TCP協(xié)議則是建立在IP協(xié)議之上的。TCP協(xié)議負(fù)責(zé)在兩臺(tái)計(jì)算機(jī)之間建立可靠連接,保證數(shù)據(jù)包按順序到達(dá)。TCP協(xié)議會(huì)通過握手建立連接,然后,對(duì)每個(gè)IP包編號(hào),確保對(duì)方按順序收到,如果包丟掉了,就自動(dòng)重發(fā)
    7.HTTP協(xié)議基于TCP協(xié)議
    8.端口的作用:同一臺(tái)計(jì)算機(jī)上跑著多個(gè)網(wǎng)絡(luò)程序。一個(gè)IP包來了之后,到底是交給瀏覽器還是QQ,就需要端口號(hào)來區(qū)分
    9、端口號(hào)小于1024的是Internet標(biāo)準(zhǔn)服務(wù)的端口,端口號(hào)大于1024的,可以任意使用
    10.UDP協(xié)議時(shí),不需要建立連接,只需要知道對(duì)方的IP地址和端口號(hào),就可以直接發(fā)數(shù)據(jù)包,不可靠、速度快
    
  • 電子郵件

    1.Email從MUA(Mail User Agent--電子郵件軟件)發(fā)出去,發(fā)到發(fā)件人郵箱所屬的MTA:Mail Transfer Agent——郵件傳輸代理(Email服務(wù)提供商),
      從發(fā)件人所屬的MTA發(fā)送到目標(biāo)郵件地址所屬的MTA(這個(gè)過程中間可能還會(huì)經(jīng)過別的MTA),
      目標(biāo)地址所屬的MTA會(huì)把郵件發(fā)送到最終目的地MDA:Mail Delivery Agent——郵件投遞代理,Email到達(dá)MDA后,就靜靜地躺在目標(biāo)服務(wù)器,等待MUA從MDA中取郵件
    2.發(fā)郵件時(shí),MUA和MTA使用的協(xié)議就是SMTP
    3.收郵件時(shí),MUA和MDA使用的協(xié)議有兩種:POP3、IMAP4
    4.MUA在發(fā)郵件時(shí),要先配置SMTP服務(wù)器,也就是你要發(fā)到哪個(gè)MTA上
        假設(shè)你正在使用163的郵箱,你就不能直接發(fā)到新浪的MTA上,因?yàn)樗环?wù)新浪的用戶,
        所以,你得填163提供的SMTP服務(wù)器地址:smtp.163.com,為了證明你是163的用戶,SMTP服務(wù)器還要求你填寫郵箱地址和郵箱口令
        類似的,從MDA收郵件時(shí),Outlook之類的郵件客戶端會(huì)要求你填寫POP3或IMAP服務(wù)器地址、郵箱地址和口令
      from email.mime.text import MIMEText
      msg = MIMEText('hello, send by Python...', 'plain', 'utf-8')
      # 輸入Email地址和口令:
      from_addr = '755766986@qq.com'
      password = 'iwfcltqyzjbpbbjj'
      # 輸入收件人地址:
      to_addr = '578179809@qq.com'
      # 輸入SMTP服務(wù)器地址:
      smtp_server = 'smtp.qq.com'
    
      import smtplib
      server = smtplib.SMTP(smtp_server, 587) # SMTP協(xié)議默認(rèn)端口是25
      server.set_debuglevel(1)
      server.starttls()
    
      server.login(from_addr, password)
      server.sendmail(from_addr, [to_addr], msg.as_string())
      server.quit()
    
  • 訪問數(shù)據(jù)庫(kù)

      # -*- coding: utf-8 -*- 
      # 導(dǎo)入MySQL驅(qū)動(dòng):
      import mysql.connector
      # 注意把password設(shè)為你的root口令:
      conn = mysql.connector.connect(user='root', password='zq112hf', database='test')
      cursor = conn.cursor()
      # 創(chuàng)建user表:
      cursor.execute('create table IF NOT EXISTS user (id varchar(20) primary key, name varchar(20))')
      # 插入一行記錄,注意MySQL的占位符是%s:
      cursor.execute('insert into user (id, name) values (%s, %s)', ['2', 'Michael'])
      print('cursor.rowcount = %d'%cursor.rowcount)
      # 提交事務(wù):
      conn.commit()
      cursor.close()
      # 運(yùn)行查詢:
      cursor = conn.cursor()
      cursor.execute('select * from user where id = %s', ('2',))
      values = cursor.fetchall()
      print(values)
      # 關(guān)閉Cursor和Connection:
      cursor.close()
      conn.close()
    
  • Web開發(fā)

1.Python內(nèi)置了一個(gè)WSGI(Web Server Gateway Interface)服務(wù)器:wsgiref模塊,效率比較低,僅供開發(fā)和測(cè)試使用
    # server.py
    # 從wsgiref模塊導(dǎo)入:
    from wsgiref.simple_server import make_server
    # 導(dǎo)入我們自己編寫的application函數(shù):
    from hello import application
    # 創(chuàng)建一個(gè)服務(wù)器,IP地址為空,端口是8000,處理函數(shù)是application:
    httpd = make_server('', 8000, application)
    print('Serving HTTP on port 8000...')
    # 開始監(jiān)聽HTTP請(qǐng)求:
    httpd.serve_forever()

    # hello.py
    def application(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        return [b'<h1>Hello, web!</h1>']
  運(yùn)行server.py來啟動(dòng)WSGI服務(wù)器
2.Web框架-Flask。每個(gè)請(qǐng)求對(duì)于一個(gè)方法
from flask import Flask
from flask import request

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def home():
    return '<h1>Home</h1>'

@app.route('/signin', methods=['GET'])
def signin_form():
    return '''<form action="/signin" method="post">
              <p><input name="username"></p>
              <p><input name="password" type="password"></p>
              <p><button type="submit">Sign In</button></p>
              </form>'''

@app.route('/signin', methods=['POST'])
def signin():
    # 需要從request對(duì)象讀取表單內(nèi)容:
    if request.form['username']=='admin' and request.form['password']=='password':
        return '<h3>Hello, admin!</h3>'
    return '<h3>Bad username or password.</h3>'

if __name__ == '__main__':
    app.run()
3. 使用模板
  在Jinja2模板中:
    {{ name }}:需要替換的變量
    {% ... %}:指令
  • 異步IO
1.異步IO模型需要一個(gè)消息循環(huán),在消息循環(huán)中,主線程不斷地重復(fù)“讀取消息-處理消息”過程
  當(dāng)遇到IO操作時(shí),代碼只負(fù)責(zé)發(fā)出IO請(qǐng)求,不等待IO結(jié)果,然后直接結(jié)束本輪消息處理,進(jìn)入下一輪消息處理過程。
  當(dāng)IO操作完成后,將收到一條“IO完成”的消息,處理該消息時(shí)就可以直接獲取IO操作結(jié)果
2.協(xié)程:一個(gè)線程執(zhí)行,效率高(子程序切換不是線程切換、不需要鎖)
  協(xié)程通過generator實(shí)現(xiàn)(包含yield關(guān)鍵字的方法就是一個(gè)generator,不知道這樣理解對(duì)不對(duì))
    def consumer():#generator
        r = ''
        while True:
            n = yield r
            if not n:
                return
            print('[CONSUMER] Consuming %s...' % n)
            r = '200 OK'

    def produce(c):#參數(shù)是一個(gè)generator
        c.send(None)
        n = 0
        while n < 5:
            n = n + 1
            print('[PRODUCER] Producing %s...' % n)
            x = c.send(n)
            print('[PRODUCER] Consumer return: %s' % x)
        c.close()

    c = consumer()#把generator賦值給變量c
    produce(c)
  執(zhí)行過程:
      1.首先調(diào)用c.send(None)啟動(dòng)生成器(generator);
      2.然后,一旦生產(chǎn)了東西,通過c.send(n)切換到consumer執(zhí)行;
      3.consumer通過yield拿到消息,處理,又通過yield把結(jié)果傳回(就是給consumer()的r賦值);
      4.produce拿到consumer處理的結(jié)果(上面的x),繼續(xù)生產(chǎn)下一條消息;
      5.produce決定不生產(chǎn)了,通過c.close()關(guān)閉consumer,整個(gè)過程結(jié)束
3. asyncio內(nèi)置了對(duì)異步IO的支持(消息循環(huán))
    import asyncio
    @asyncio.coroutine#標(biāo)記為coroutine
    def hello():
        print("Hello world!")
        # 異步調(diào)用asyncio.sleep(1):
        r = yield from asyncio.sleep(1)#執(zhí)行到這里會(huì)直接中斷并去執(zhí)行EventLoop中其他可以執(zhí)行的coroutine
                                       #過了1秒返回一個(gè)None(r = None),CPU再來執(zhí)行后面的代碼
        print("Hello again!")
    # 獲取EventLoop:
    loop = asyncio.get_event_loop()
    # 執(zhí)行coroutine
    loop.run_until_complete(hello())#把協(xié)程放到消息隊(duì)列里執(zhí)行,如果有多個(gè)使用wait:asyncio.wait([hello(),A(),B()])
    loop.close()#記得關(guān)閉循環(huán)
4.Python 3.5開始
    @asyncio.coroutine = async
    yield from = await
5. aiohttp則是基于asyncio實(shí)現(xiàn)的HTTP框架
    import asyncio

    from aiohttp import web

    async def index(request):
        await asyncio.sleep(0.5)
        return web.Response(body=b'<h1>Index</h1>')

    async def hello(request):
        await asyncio.sleep(0.5)
        text = '<h1>hello, %s!</h1>' % request.match_info['name']
        return web.Response(body=text.encode('utf-8'))

    async def init(loop):
        app = web.Application(loop=loop)
        app.router.add_route('GET', '/', index)
        app.router.add_route('GET', '/hello/{name}', hello)
        srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8000)
        print('Server started at http://127.0.0.1:8000...')
        return srv

    loop = asyncio.get_event_loop()
    loop.run_until_complete(init(loop))
    loop.run_forever()
  • 其他
1.with關(guān)鍵字的用法:
      with expression as variable:
          with block
  該代碼快的執(zhí)行過程是: 1.先執(zhí)行expression,然后執(zhí)行該表達(dá)式返回的對(duì)象實(shí)例的__enter__函數(shù),然后將該函數(shù)的返回值賦給as后面的變量。(注意,是將__enter__函數(shù)的返回值(返回expression的值)賦給變量) 
                     2.然后執(zhí)行with block代碼塊,不論成功,錯(cuò)誤,異常,在with block執(zhí)行結(jié)束后,會(huì)執(zhí)行第一步中的實(shí)例的__exit__函數(shù)。)
2.
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,055評(píng)論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評(píng)論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評(píng)論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,346評(píng)論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,889評(píng)論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評(píng)論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,118評(píng)論 0 286
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,637評(píng)論 1 333
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,558評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,739評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評(píng)論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 43,980評(píng)論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評(píng)論 1 280
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,347評(píng)論 3 390
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,702評(píng)論 2 370

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