廖雪峰的Python笔记 发表于 2017-03-08 | 分类于 note | 阅读次数 | 123456类名:驼峰式 和首字母缩略词:HTTPWriter 优于 HttpWriter。变量名:lower_with_underscores方法名和函数名:lower_with_underscores模块名:lower_with_underscores.py(不带下划线的名字更好)常量名:UPPER_WITH_UNDERSCORES预编译的正则表达式:name_re 1234567891011121314151617不要去刻意对齐注释,后期维护代码会增加麻烦采用#来进行多行注释标准方法注释 def f(a, b): """ To sum two ints :arg: a: int b: int :return: c: int """ c = a + b return c if __name__ == '__main__': print(f.__doc__) 123456789101112131415print("I'm ok") # I'm ok 字符串内外引号要不同,否则转义 print('I"m ok') # I"m okprint('I\'m ok') # I'm ok 抑制转义print(r'I\'m ok') # I\'m ok 抑制转义print('''aaa # 换行打印bbb ccc''') print(9/3) # 3.0 浮点型除法print(9//3) # 3 取整print(9 % 3) # 0 取余print('%10s:%10s' %('a','b') # 插入变量,10s控制长度可对齐print(), # 逗号抑制换行print('start : {:0.3f}'.format(0.123456))print('start : {:3s}'.format('a'))print('start : {:5s}{:5s} '.format('a', 'b')) 1234567s = 'My name is captain's_list = s.split()for i in range(len(s_list)): s_list[i] = s_list[i].upper() # 可以全变大写,lower小写for i in s_list: # 不可全变大写,for循环中的i是临时变量 i = i.upper()s_caps_equal = ' '.join(s_list) # join的用法:‘分隔符’.join(字符串序列) 1234567891011L = [x for x in range(6)] # [0, 1, 2, 3, 4, 5] 列表生成式L = list(range(0, 6)) # [0, 1, 2, 3, 4, 5]L1 = L[0:4] # [0, 1, 2, 3]L2 = L[-4:] # [2, 3, 4, 5]L3 = L[:4:2] # [0, 2]L4 = L[::2] # [0, 2, 4]# tuple也可以用切片操作,只是操作的结果仍是tuple# 字符串也可以用切片操作,只是操作结果仍是字符串 1234567891011# dict的items()可以同时迭代key和valuefor k, v in d.items(): print(k, '=', v)for k in d: print(k, d[k]) # Python内置的enumerate函数可以把一个list变成索引-元素对,可访问下标l = ['a', 'b', 'c']for i, v in enumerate(l): if i == 2: print(v) 123l = (x for x in range(6)) # 列表生成式[] vs 生成器(), 循环访问不变/next(l), 防止内存爆for i in l: print(i) 123456789101112131415161718192021def fib(n): a, b, i, res = 1, 1, 1, 0 while i < n: yield a temp = a a = b b = temp + b i = i + 1 res = res + temp return resf = fib(6) # 返回生成器对象# for v in f:# print(v) # 打印生成器yield的内容1,1,2,3,5while True: try: print(next(f)) except StopIteration as e: print(e.value) # 打印return的res=12 break 123456789101112def f(x): return x*xr = map(f, list(range(1, 6))) # map将传入的函数依次作用到序列的每个元素,好处是能一眼看明白print(r) # <map object at 0x031721F0>, r是一个迭代器,是惰性序列res = list(r)print(res) # [1, 4, 9, 16, 25]******from functools import reducedef f(x, y): return x*10 + yr = reduce(f, list(range(1, 6))) # reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)print(r) # 12345, 返回类型为参数类型 12345678from functools import reduce # map/reduce的应用,思想:对序列做同一函数运算def str2int(s): def char2num(i): return {'0':0, '1':1, '2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9}[i] def fn(x, y): return x*10 + y return reduce(fn, list(map(char2num, s)))print(str2int('12345')) # int:12345 123456# filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素def is_odd(x): return x % 2 == 1l = filter(is_odd, list(range(1, 6)))print(l) # <filter object at 0x036D21B0>print(list(l)) # [1, 3, 5] 12345678910111213141516171819202122def generate_num(): n = 1 while True: n = n + 2 yield ndef not_divisible(n): return lambda x: x % n > 0 # 匿名函数lambda 参数:返回值def prime(): yield 2 it = generate_num() while True: n = next(it) yield n it = filter(not_divisible(n), it)for i in prime(): # 求素数,结合了generator和filter, 理解了即理解了generator和filter if i < 100: print(i) else: break 12345# sorted()函数也是一个高阶函数,可以接收一个key函数来实现自定义的排序sorted([36, 5, -12, 9, -21])sorted([36, 5, -12, 9, -21], key=abs)sorted(['bob', 'about', 'Zoo', 'Credit'])sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower) 12345678910111213def log(func): # 装饰器 def wrapper(*args, **kw): print('call %s' % func.__name__) return func(*args, **kw) return wrapper@logdef now(): print('hello world')now() # call now hello world, @log放到now()函数的定义处,相当于执行了语句:now = log(now) # 现在同名的now变量指向了新的函数now = log(now) 12345678910111213# 返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量def my_sum(l): def do_sum(): # 不需要立刻计算,而是在后面的代码中,根据需要再计算 res = 0 for i in l: res = res + i return res return do_sumif __name__ == '__main__': f = my_sum(list(range(1, 6))) print(f) # <function my_sum.<locals>.do_sum at 0x02B7C618> print(f()) # 15 1234def my_abs(x): if not isinstance(x, (int, float)): # 判断参数类型 raise TypeError('bad operand type') pass 123456def power(x, n=2): # 设置默认参数 power(2)=4, power(2,3)=8 s = 1 while n > 0: n = n - 1 s = s * x return s 12if __name__=='__main__': # 运行测试,其他py文件引用此句将失效 test() # 特殊变量:__xx__,自己定义不能用特殊变量 1234567891011def _f1(name): # private,继承时将内部逻辑隐藏,加1/2个下划线 return 'Hello, %s' % name def _f2(name): return 'Hi, %s' % namedef f(name): # public if len(name) > 3: return _f1(name) else: return _f2(name) 1234567891011121314class Student(object): # 括号中为父类,没有就用object def __init__(self, name, score): # 第一个参数永远是self,向创建的实例本身 self.__name = name self.__score = score # private:属性的名称前加上两个下划线 def print_score(self): # 不用传参,类内可直接调用 print('%s: %s' % (self.__name, self.__score)) if __name__ == '__main__': s1 = Student('zp', 23) s1.print_info() print(s1.__name) # 会报错没有此属性,因为是private属性 print(s1.__age) 123456789101112class Animal(object): def run(self): print('Animal is running...') class Dog(Animal): # Dog继承Animal def run(self): print('Dog is running...')dog = Dog()dog.run() # Dog is running... res1 = isinstance(dog, Dog) # 子类的run()覆盖了父类的run(),体现多态res2 = isinstance(dog, Animal) # 都为True,多态本质 123type()判断对象类型isinstance()判断有继承的class类型dir()获得一个对象的所有属性和方法,无论private或public 12class Student(object): name = 'Student' # 类属性 优先级低于self,没有实例属性则访问类属性 1234567class Student(object): __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称 s = Student() s.name = 'Michael' # 绑定属性'name's.age = 25 # 绑定属性'age's.score = 99 # AttributeError 123主线都是单一继承下来的,需要“混入”额外的功能可通过多重继承实现,这种设计通常称之为MixInclass MyTCPServer(TCPServer, ForkingMixIn): # 多进程模式的TCP服务 pass 1234567class Student(object): def __init__(self, name): self.name = name def __str__(self): # 定制类,打印的好看 return 'Student object (name: %s)' % self.nameprint(Student('Michael')) # Student object (name: Michael) 1234567class Student(object): def __init__(self, name): self.name = name def __str__(self): # __str__()返回用户看到的字符串 return 'Student object (name=%s)' % self.name __repr__ = __str__ # __repr__()返回程序开发者看到的字符串,是为调试服务的 # 通常__str__()和__repr__()都是一样 12345678def say_hello(self, name): print('hello %s' % name)zp = type('Hello', (object,), dict(hello=say_hello)) # type动态创建类print(type(zp)) # zp是type类型,可理解为zp是Hello类的动态创建器cwy = zp()print(type(cwy)) # cwy是Hello类型cwy.hello('cwy') 12345678910111213class ListMetaClass(type): # 元类 def __new__(cls, name, bases, attrs): attrs['add'] = lambda self, value: self.append(value) # add=append return type.__new__(cls, name, bases, attrs)class MyList(list, metaclass=ListMetaClass): pass # 指示Python解释器在创建MyList时,要通过ListMetaclass.__new__()来创建L = MyList()L.add(1) # [1]print(L)L.append(2)print(L) # [1,2] 12345from enum import EnumMonth = Enum('Month', ('Jan', 'Feb', 'Mar')) # 非精确的枚举类print(Month.Jan.value) # value属性是自动赋给成员的int常量,默认从1开始for name in Month: print(name, name.value) 123456789from enum import Enum, unique@unique # @unique装饰器可以帮助检查没有重复值class Weekday(Enum): # 精确的枚举类 Sun = 0 Mon = 1 Tue = 2print(Weekday.Sun.value)for name in Weekday: print(name, name.value) 123456789101112def foo(s): n = int(s) if n==0: raise ValueError('invalid value: %s' % s) return 10 / n # 中断自己抛出错误,让调用函数去处理错误def bar(): try: foo('0') except ValueError as e: print('ValueError!') raise # 当前函数不知道应该怎么处理该错误,继续往上抛让顶层调用者处理 123456789import logging logging.basicConfig(level=logging.INFO)s = '0'n = int(s)logging.info('n = %d' % n)print(10 / n)# logging代替print,logging级别有debug、info、warning、error等几个级别,当我们指定如level=INFO时,logging.debug就不起作用了;logging通过简单的配置,一条语句可以同时输出到不同的地方,比如console和文件 123read()会一次性读取文件的全部内容,内存易爆readlines()一次性读取所有内容并按行返回listreadline()每次读取一行内容 123456r:读w: 写 # 写/追加不存在则创建,二进制同r+:读写w+:读写a:追加写a+: 追加读写 12345with open('dsjtzs_txfz_training_sample.txt') as f: line = f.readline() while line: print(line) line = f.readline() # 非一次性读进内存 12345678import os dirs = [x for x in os.listdir('C:\\Users\\captianzp\\Documents') if os.path.isdir(os.path.join('C:\\Users\\captianzp\\Documents', x))]print(dirs)# 遍历当前目录,isdir采用绝对路径,os.path.join方便连接路径print(os.path.split('C:\\Users\\captianzp\\Documents')) # 分割路径 ('C:\\Users\\captianzp', 'Documents'),后一部分总是最后级别的目录或文件名 1234567891011121314import pickle # 序列化: 把变量从内存中存储到文件中d = {'name': 'Bob', 'age': 23, 'score': 90}res = pickle.dumps(d) # pickle.dumps()方法把任意对象序列化成一个bytesd = pickle.loads(res) # pickle.loads()方法反序列化出对象f = open('dump.txt', 'wb')pickle.dump(d, f) # pickle.dump()直接把对象序列化后写入一个文件f.close()f1 = open('dump.txt', 'rb')d = pickle.load(f1) # pickle.load()从一个文件中直接反序列化出对象f1.close() 1234567891011import jsond = {'name': 'Bob', 'age': 23, 'score': 90}print(type(d)) # dictres = json.dumps(d) print(type(res)) # str,json.dumps()方法把任意对象序列化成一个bytes d = json.loads(res)print(type(d)) # dict,json.loads()方法反序列化出对象# json.dump()、json.load()用法与pickle相同,写入文件