背景:适合有一定基础的哈
一、基础
#!/usr/bin/env python3 # mac或linux 点击文件可直接运行
# -*- coding: utf-8 -*- # 配置编码是utf-8
1.1、打印
| print("hello world") | 直接打印 |
|---|---|
| print(2**10) | 2的10次方 |
| print('a', 'b', 'c') | 一行打印多个,空格分割 |
| print('100+200=', 100 +200) | 计算 |
| name = input() | 手动输入 |
| name = input("please enter your name: ") | 添加说明解释的手动输入 |
# 打印
# print("hello world")
# print(2**10)
# print('你好, 世界!')
# ## 逗号分割
# print('a', 'b', 'c')
# print('100+200=', 100 +200)
# 手动输入
# name = input()
# print('hello', name)
# name = input("please enter your name: ")
# print('hello', name)
# print('1024 * 768 =', 1024 * 768)
1.2、数据类型和变量
| c = True | 布尔类型 True、False,其他类型就是正常,并且定义变量不需要指定类型 |
|---|
# 数据类型和变量
# print(100_00 * 10)
# print('I\'m \"ok\"')
# print(True or False)
# a = 1
# b = 'T'
# c = True
# a = 'a'
# print(a, b, c)
# 字符串及编码方式
# print(ord('A'))
# print('\u4e2d\u6587')
# print(len('A'))
1.3、格式化
| 占位符 | 替换内容 |
|---|---|
| %d | 整数 |
| %f | 浮点数 |
| %s | 字符串 |
| %x | 十六进制整数 |
| print('hello, %s, 整数: %d, 浮点数: %f' % ('田', 1, 1.1)) | %格式化 |
|---|---|
| print('%2d-%02d' % (3, 1)) | %02d |
| print('%.2f' % 3.1415926) | %.2f |
| print('hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.123)) | format格式化 |
| print(f'The area of a circle with radius {r} is {s:.2f}') | f格式化 |
# # 格式化
# print('hello, %s, 整数: %d, 浮点数: %f' % ('田', 1, 1.1))
# print('%2d-%02d' % (3, 1))
# print('%.2f' % 3.1415926)
# print('hello, {0}, 成绩提升了 {1:.1f}%'.format('小明', 17.123))
# r = 2.5
# s = 3.14 * r ** 2
# print(f'The area of a circle with radius {r} is {s:.2f}')
# print('hello, %s, 整数: %d, 浮点数: %.2f' % ('田', 1, r))
1.4、list、tuple、dict、set
| list 可变数组 | a = ['e', 'a', 'b', 'c'] a.sort() print(len(a)) print(a[0]) print(a[-1]) # 最后一个 a.append('d') a.insert(1, 'jack') a.pop() a.pop(1) | |
|---|---|---|
| tuple 不可变数组 | t = (1, 2) t2 = (1, 2, [3, 4]) t2[2][0] = 'x' | |
| dict 类似于Map | d = {'zhangsan': 18, 'lisi': 19, 'wangwu': 20} print(d['zhangsan']) print(d.get('zhangsan')) print(d.get('laoliu', -1)) # 不存在返回-1 d.pop('lisi') d['aaa'] = 11 | |
| set 无序,不重复 | s = {1, 1, 2, 3} s.add(9) s.remove(3) d = {1, 2, 3, 4, 5} print(s & d) # 取交集 print(s | d) # 取并集 |
# list
# a = ['e', 'a', 'b', 'c']
# a.sort()
# print(a)
# aa = 'abcde'
# print(aa.replace('a', 'f')) # 返回了一个新的字符串
# print(aa)
# print(len(a))
# print(a[0])
# print(a[-1]) # 最后一个
# a.append('d')
# print(a)
# a.insert(1, 'jack')
# print(a)
# a.pop()
# print(a)
# a.pop(1)
# print(a)
# a[1] = [1, 2, 3]
# print(a)
# tuple 不可变数组
# t = (1, 2)
# print(t)
# t2 = (1, 2, [3, 4])
# t2[2][0] = 'x'
# print(t2)
# # dict 类似于Map
# d = {'zhangsan': 18, 'lisi': 19, 'wangwu': 20}
# print(d['zhangsan'])
# print(d.get('zhangsan'))
# print(d.get('laoliu', -1)) # 不存在返回-1
# d.pop('lisi')
# print(d)
# d['aaa'] = 11
# print(d)
# # set
# s = {1, 1, 2, 3}
# print(s)
# s.add(9)
# print(s)
# s.remove(3)
# print(s)
# d = {1, 2, 3, 4, 5}
# print(s & d) # 取交集
# print(s | d) # 取并集
1.5、条件判断、循环、模式匹配
| if elif else 条件判断 | python # 条件判断 # age = int(input("age:")) # if age >= 60: # print("退休了") # elif age >= 30: # print("还得在干30年") # else: # print("好好学习把!") | ||
|---|---|---|---|
| match 变量: case 'A': case _: | ```python ## 模式匹配 # score = input("请输入你的score: ") # match score: # case 'A': # print('score is A') # case 'B': # print('scope is B') # case _: # 表示匹配到其他情况 # print('其他情况') ## 复杂模式匹配 # age = int(input('请输入你的age: ')) # match age: # case x if x < 10: # print(x, ":", age) # case 11 | 12: # print('11 | 12') # case _: # print('其他情况') # args = ['aa', 'bb', 'cc'] # match args: # case ['aa']: ## 只有aa的时候 # print("列表中只有aa") # case['aa', file1, *files]: # 包含bb, 并且第二个字符放到file1上, 任意一个字符放到files # print('第一个是aa, file1: %s, files: %s' % (file1, files)) # case _: # print('其他情况') ``` |
| for 循环 | python # 循环 # names = ['zhangsan', 'lisi', 'wangwu'] # for name in names: # print(name) # print(list(range(5))) # range生成0-4 # sum = 0 # for x in range(101): # sum += x # print(sum) | ||
| while 循环 | python # n = 1 # while n <= 100: # if (n > 10): # break; # print(n) # n += 1 # print('end') # n = 1 # while n <= 100: # n += 1 # if n % 2 == 0: # continue # print(n) |
二、函数
2.1、内置函数
| abs() 绝对值 | print(abs(-100)) |
|---|---|
| max() 取最大 | python a = [1, 2, 3, 4, 5] print(max(1,2,3,4,5)) print(max(a)) |
| int() 转成int | print(int('1')) |
| float() 转成float | print(float('1.1')) |
| str() 转成str | print(str(1.1)) |
| bool() 转成布尔 | print(bool(1)) |
| hex() 转换成16进制 | print(hex(255)) |
| import math | math.cos(angle) # 余弦 math.sin(angle) # 正弦 math.pi # Π math.sqrt(2) # 求算数平方根 |
2.2、定义函数
| def 函数名(变量1, 变量2): 函数内容 return x | python # 自定义函数 # def my_abs(x): # if x >0: # return x # else: # return -x # print(my_abs(-999)) # def che_my_abs(x): # if not isinstance(x, (int, float)): # raise TypeError('bad operand type') # if x > 0: # return x # else: # return -x; # print(che_my_abs('A')) |
|---|---|
| 空函数 pass | python # 空函数 # def nop(): # pass # age = 1 # if age >= 18: # pass |
| 返回多个值 | python # 返回多个值 import math def move(x, y, step, angle=0): nx = x + step * math.cos(angle) ny = y - step * math.sin(angle) return nx, ny x,y = move(100, 100, 60, math.pi / 6) print(x, y) # 其实返回的是tuple z = move(100, 100, 60, math.pi / 6) print(z) # 求算数平方根 print(math.sqrt(2)) # 求根公式函数 def quadratic(a, b, c): x1 = (-b + math.sqrt(b**2 - 4 * a * c)) / 2 * a x2 = (-b - math.sqrt(b**2 - 4 * a * c)) / 2 * a return x1, x2 print(quadratic(1, 2, 1)) |
| 参数默认值 避坑:设置默认值为空集合的时候可以设置成None不可变对象 | python def enroll(name, gender, age = 6, city = 'bj'): print(name) print(gender) print(age) print(city) enroll("zs", '一') enroll('ls', 'er', 7, 'tj') def add_end(l = []): l.append('end') return l print(add_end([1])) print(add_end()) # ['end', 'end'] print(add_end()) # 设置None 不可变对象 def add_end2(l = None): if (l is None): l = [] l.append('end') return l print(add_end2([1])) print(add_end2()) # ['end', 'end'] print(add_end2()) |
| 可变参数 *:0个或多个参数的tuple | python def calc(*numbers): sum = 0 for n in numbers: sum = sum + n return sum print(calc(1,2,3)) |
| 关键字参数 **: 0个或多个属性值,注意写法 | python def person(name, age, **kk): print('name:', name, 'age:', age, 'kk:', kk) person('tjx', 18) person('tjx', 18, city='bj') person('tjx', 18, city='bj', jobe = 'Engineer') extra = {'city': 'bj', 'jobe': 'Engineer'} person('tjx', 18, **extra) |
| *:后面的参数名必须是city,job 如果有可变参数, 后面参数名也是必须相同 | python def person(name, *, city, job): print('name', name, city, job) person('tjx', city = 'bj', job='job') def person2(name, *args, city): print(name, args, city) person2('tjx', 12, 13, city='bj') |
| 递归调用 | python def fact(n): if n == 1: return 1 return n * fact(n - 1) print(fact(3)) # 尾递归 def fact2(n): return fact_iter(n ,1) def fact_iter(num, product): if num == 1: return product return fact_iter(num-1, num*product) print(fact2(6)) |
三、高级特性
| 切片 [0:4] 0-3 [:4]前4个 [-2:]倒数后两个 [::5] 隔5个取 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. l = list(range(100)) print(l[0:3]) print(l[:3]) # 倒数后两个 print(l[-2:]) print(l[-3:-1]) #前10个数每2个取一个 print(l[:10:2]) #每5个取一个 print(l[::5]) #打印全部数据 print(l) print(l[:]) print('abc'[:2]) #touple做切片 print((1,2,3)[:2]) |
|---|---|
| 迭代 遍历list、遍历dict 判断是否可以遍历 带下标遍历enumerate 遍历[(),()] | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. d = {'a':1, 'b': 2, 'c':3} for key in d: print(key) for value in d.values(): print(value) for k,v in d.items(): print(k, v) for a in 'abc': print(a) from collections.abc import Iterable print(isinstance('abc', Iterable)) # str是否可迭代 print(isinstance(123, Iterable)) # 整数是否可迭代 #带下标循环enumerate函数 for i, value in enumerate(['A', 'B', 'C']): print(i, value) for i,j in [(1,'a'), (2, 'b')]: print(i,j) |
| 列表生成器 for list = [变量表达式 循环体] | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. print([x * x for x in range(1,11)]) print([x * x for x in range(1,11) if x % 2 == 0]) print([m + n for m in 'ABC' for n in 'abc']) # 目录名 import os print([d for d in os.listdir('.')]) d = {'A': 'a', 'B': 'b', 'C': 'c'} print([k + '=' + v for k, v in d.items()]) s = ['Hello', 'World'] print([l.lower() for l in s]) |
| 列表生成器 if list = [变量表达式 循环体 if 条件] list = [变量表达式 if 条件 else 表达式 循环体] | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. print([x * x for x in range(1, 11) if x % 2 == 0]) print([x if x % 2 == 0 else -x for x in range(1, 11)]) L1 = ['Hello', 'World', 18, 'Apple', None] L2 = [x.lower() for x in L1 if isinstance(x, str)] # 测试: print(L2) if L2 == ['hello', 'world', 'apple']: print('测试通过!') else: print('测试失败!') |
| 生成器 | python g = (x * x for x in range(1, 11)) print(g) print(next(g)) print(next(g)) for x in g: print(x) def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return 'done' fib(10) |
| 函数生成器 yield | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. def odd(): print('step 1') yield(1) print('step 2') yield(2) print('step 3') yield(3) #print(odd()) #next(odd()) #print(next(odd())) for x in odd(): print(x) |
| 迭代器 凡是可作用于 for循环的对象都是Iterable类型;凡是可作用于 next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;集合数据类型如 list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. from collections.abc import Iterable, Iterator print(isinstance([], Iterable)) print(isinstance({}, Iterable)) print(isinstance('abc', Iterable)) print(isinstance((x for x in range(10)), Iterable)) print(isinstance(100, Iterable)) print(isinstance([], Iterator)) print(isinstance({}, Iterator)) print(isinstance('abc', Iterator)) print(isinstance((x for x in range(10)), Iterator)) print(isinstance(iter([]), Iterator)) |
四、函数式编程
4.1、高阶函数
| 函数可以赋值给变量 f = abs f(-10) | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. f = abs print(f) print(f(-10)) def add(x, y, f): return f(x) + f(y) print(add(-5, -6, abs)) |
|---|---|
| Iterator = map(函数, Iterable) list(map(函数, Iterable)) 依次调用函数并返回结果 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. def f(x): return x * x l = map(f, [1, 2, 3]) print(list(l)) # 数字转字符串 print(list(map(str, [1,2,3]))) |
| reduce(函数, Iterable) 循环调用函数并返回结果 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. from functools import reduce def add(x, y): return x + y print(reduce(add, [1,2,3,4,5])) def fn(x, y): return x * 10 + y print(reduce(fn, [1,2,3])) def char2num(s): digits = {'0': 0, '1': 1, '2': 2} return digits[s] print(reduce(fn, map(char2num, '120'))) def normalize(name): return name[0].upper() + name[1:].lower() L1 = ['adam', 'LISA', 'barT'] L2 = list(map(normalize, L1)) print(L2) def prod(L): def mul(x, y): return x * y return reduce(mul, L) print('3 * 5 * 7 * 9 =', prod([3, 5, 7, 9])) if prod([3, 5, 7, 9]) == 945: print('测试成功!') else: print('测试失败!') |
| Iterator = filter(函数变量, Iterable) 过滤器 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. def is_odd(n): return n % 2 == 1 print(list(filter(is_odd, [1,2,3,4,5]))) def not_empty(s): return s and s.strip() print(list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))) |
| sort(集合) sort(集合, key = 函数) sort(集合, key = 函数, reverse = True) | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. print(sorted([1,5, -1])) print(sorted([1, 5, -2], key=abs)) print(sorted(['Zab','abc'])) print(sorted(['Zab', 'abc'],key=str.lower)) print(sorted(['Zab', 'abc'],key=str.lower, reverse = True)) L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] def by_name(t): return t[0] L2 = sorted(L, key=by_name) print(L2) |
4.2、返回函数
| 可以返回函数,f()才是调用 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. def lazy_sum(*args): def sum(): ax = 0 for n in args: ax = ax + n return ax return sum f = lazy_sum(1, 2, 3) print(f) print(f()) |
|---|---|
| 闭包,引用了函数外的变量 | python def count(): fs = [] for i in range(1, 4): def f(): return i * i fs.append(f) return fs f1, f2, f3 = count() print(f1()) print(f2()) print(f3()) def count2(): def f(j): def g(): return j * j return g fs = [] for i in range(1, 4): fs.append(f(i)) # 立即执行 return fs f11, f22, f33 = count2() print(f11()) print(f22()) print(f33()) |
| 闭包 只是读外部变量可以,如果要给外部变量赋值则是nonlocal x | python def inc(): x = 0 def fn(): # 仅仅是读取 return x + 1 return fn ff = inc() print(ff()) print(ff()) def inc2(): x = 0 def fn(): nonlocal x x = x + 1 return x return fn fff = inc2() print(fff()) print(fff()) |
4.3、匿名函数
| lambda 函数参数: 表达式 | python l = list(map(lambda x : x * x, [1, 2, 3])) print(l) |
|---|
4.4、装饰器
| @装饰器方法 对方法进行增强 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. def log_decorator(func): def wrapper(): print("[日志] 函数开始执行") func() print("[日志] 函数执行结束]") return wrapper # 语法糖 @等价于 hello = log_decorator(hello) @log_decorator def hello(): print("你好Python装饰器") hello() |
|---|---|
| 对函数中带参数和返回值的装饰器 *args, **kwargs 固定写法 位置, 参数 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. def log_decorator(func): # *args, **kwargs 固定写法 位置, 参数 def wrapper(*args, **kwargs): print("[日志] 函数开始执行") res = func(*args, **kwargs) print("[日志] 函数执行结束]") return res return wrapper # 语法糖 @等价于 hello = log_decorator(hello) @log_decorator def hello(a, b): print("你好Python装饰器") return a + b print(hello(1, 2)) |
| 装饰器自身带参数 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. def log_decorator(level): def decorator(func): # *args, **kwargs 固定写法 位置, 参数 def wrapper(*args, **kwargs): print("[日志%s] 函数开始执行" % (level)) res = func(*args, **kwargs) print("[日志%s] 函数执行结束]" % (level)) return res return wrapper return decorator # 语法糖 @等价于 hello = log_decorator(hello) @log_decorator('debug') def hello(a, b): print("你好Python装饰器") return a + b print(hello(1, 2)) |
4.5、偏函数
| 固定参数,可以固定关键字,可以固定位置 注意:关键词不能固定第一个 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. print(int('1010', base=2)) from functools import partial # 固定关键词 bin2int = partial(int, base=2) print(bin2int('1010')) # 固定位置 def fun(a, b, c): return a + b + c * 10 f1 = partial(fun, 10) print(f1(2, 3)) # 固定关键词, 不能是第一个参数 f2 = partial(fun, c = 100) print(f2(1, 2)) |
|---|
五、模块
5.1、使用模块
| import 导入模块 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. 'a test module' __author__ = 'tjx' import sys def test(): args = sys.argv if (len(args) == 1): print('1个参数') elif (len(args) == 2): print('2个参数') else: print('太多了!!!') # 如果是直接运行则调用函数 if __name__ == '__main__': test() |
|---|---|
| _:私有函数 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. # _表示私有方法 def _private_1(name): return 'hello, %s' % name def _private_2(name): return 'hi, %s' % name def greeting(name): if (len(name) < 3): return _private_2(name) else: return _private_1(name) print(greeting('tjx')) |
5.2、安装第三方模块
6、面向对象编程
6.1、类和实例
| class 类名(继承的类): 初始化方法: def init(self, 参数): | python class Student(object): def __init__(self, name, score): self.name = name self.score = score def print_score(self): print(self.name, self.score) s = Student('张三', 18) print(s.name) print(s.print_score()) |
|---|
6.2、私有属性 get set
| __变量名 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. class Student(object): def __init__(self, name, score): self.__name = name self.__score = score def get_name(self): # 只能通过公有方法获取私有变量 return self.__name def get_score(self): return self.__score def set_score(self, score): self.__score = score def set_name(self, name): self.__name = name s = Student('张三', 18) s.set_score(20) s.set_name('zs') print(s.get_name()) print(s.get_score()) |
|---|
6.3、继承和多态
| class Animal(继承的类): 判断class类型用instance | python class Animal(object): def run(self): print('Animal is running...') class Dog(Animal): pass class Cat(Animal): pass dog = Dog(); print(dog.run()) print(isinstance(dog, Animal)) |
|---|
6.4、获取属性信息
| type(): 判断基本类型 instance(): 判断class dir(): 获取class的所有非私有的属性和方法 hasattr(): 判断class是否有这个属性(只能判断非私有) getattr(): 获取class的这个属性(只能获取非私有) setatt(): 设置class的这个属性(只能设置非私有) | python class Animal(object): def __init__(self, name): self.name = name def run(self): print('Animal is running...') class Dog(Animal): pass class Cat(Animal): pass animal = Animal('animal'); dog = Dog('dog'); print(dog.run()) print(isinstance(dog, Animal)) print(type(dog)) print(type(123)) def test(): pass print(type(test)) # print(dir('a')) print(dir(dog)) print(hasattr(dog, 'run')) print(hasattr(dog, 'name')) print(hasattr(animal, 'name')) print(setattr(animal, 'name', 'animal123')) print(getattr(animal, 'name')) |
|---|
6.5、实例属性和类属性
| 实例属性 在init中 类属性在类中定义 | python class Student(object): # 类属性 name = 'Student' def __init__(self, age): # 实例属性 self.age = age print(Student.name) student = Student(10) print(student.name) student.name = 'Student123' print(student.name) print(Student.name) del student.name print(student.name) |
|---|
7、面向对象高级编程
7.1、slots
| 给实例动态添加属性和方法 实例.属性值 = 1 实例.方法名= 方法名 (只给这个实例增加) 类名.方法名= 方法名(给这个类添加方法) | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. class Student(object): pass s = Student() s.name = 'Michael'; print(s.name) def set_age(self, age): self.age = age from types import MethodType s.set_age = MethodType(set_age, s) s.set_age(25); print(s.age) def set_score(self, score): self.score = score Student.set_score = set_score s2 = Student() s2.set_score(90) print(s2.score) s.set_score(99) print(s.score) |
|---|---|
| slots:只允许动态添加自定义的属性 注意:对继承实现的类不生效 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. class Student(object): __slots__ = ('name', 'age') # touple定义允许绑定的属性的名称 class GraduateStudent(Student): pass s = Student() gs = GraduateStudent() s.name = 'zs' # s.score = 90 gs.name = 'gs' gs.score = 90 print(s.name) print(gs.name) print(gs.score) |
7.2、@property
| 可以理解为set和get方法的变种或简化 property:把方法发变成只读属性 属性名.setter: 把方法变成setter方法 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. class Student: def __init__(self, name): self._name = name # @property: 把这个方法变成【只读属性】 注意方法名和属性名不能相同 @property def name(self): return self._name # @属性名.setter: 、把这个方法变成【可写属性】 @name.setter def name(self, new_name): if len(new_name) < 2: raise ValueError("名字太短了!") self._name = new_name s = Student("张三") # 直接当属性用 print(s.name) s.name = "李思" print(s.name) |
|---|
7.3、多继承
| class 类名(类1, 类2) | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. class Animal: pass # 拓展功能 一般加上 MixIn class RunnableMixIn: def run(self): print("run......") class FlyableMixIn: def fly(self): print("fly.....") class Dog(Animal, RunnableMixIn): pass d = Dog() d.run() |
|---|
7.4、定制类
| str: 打印实例自动调用 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. class Student(object): def __init__(self, name): self._name = name # 打印类 def __str__(self): return 'Student object (name: %s)' % self._name # 调试服务 看到的 对象 __repr__ = __str__ print(Student("张三")) |
|---|---|
| iter:变类可以按照for in 循环获取next的值 next:返回的值 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. 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 if self.a > 20: raise StopIteration() return self.a for n in Fib(): print(n) |
| getitem:类变成list,可以f[0] [1:5]切片调用 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. class Fib(object): def __getitem__(self, n): if isinstance(n, int): # n是索引 a, b = 1, 1 for x in range(n): a, b = b, a + b return a if isinstance(n, slice): # n是切片 start = n.start stop = n.stop if start is None: start = 0 a, b = 1, 1 L = [] for x in range(stop): if x >= start: L.append(a) a, b = b, a + b return L f = Fib(); print(f[0]) print(f[0:5]) |
| getattr:不存在的属性走这个方法,应用的话可以链式调用 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. class Student(object): def __init__(self): self.name = 'Michael' # 不存在的属性走这个方法 def __getattr__(self, attr): if attr == 'scope': return 99 s = Student(); print(s.scope) 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__ print(Chain().status.user.timeline.list) |
| call:把实例变成函数调用 callable():判断一个对象是不是可调用对象 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. class Student(object): def __init__(self, name): self.name = name # 把实例变成函数调用 def __call__(self): print('My name is %s.' % self.name) s = Student("张三") s() #判断一个对象是不是可调用对象 print(callable(Student("李四"))) print(callable([1, 2])) |
7.5、枚举
| 方式一:Enum(key, (value1, value2)) 方式二: @unique class Weekday(Enum): | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. from enum import Enum Month = Enum('Month', ('Jan','Feb')) for name, member in Month.__members__.items(): print(name, '=>', member, ',', member.value) from enum import Enum, unique # unique 检查值不能重复 @unique class Weekday(Enum): Sun = 0 Mon = 1 print(Weekday.Sun) day1 = Weekday.Mon print(day1) print(day1.value) print(day1 == Weekday.Mon) print(Weekday(1)) |
|---|
8、错误调试测试
8.1、错误处理
| try: xxx except 异常类型 as e: xxx else: 不报异常处理 finally: xxx | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. 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...") print("END") |
|---|---|
| 调用栈 Traceback (most recent call last): File "script.py", line 13, in main() File "script.py", line 11, in main bar('0') File "script.py", line 8, in bar return foo(s) * 2 File "script.py", line 5, in foo return 10 / int(s) ZeroDivisionError: division by zero Exited with error status 1 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. # err.py: def foo(s): return 10 / int(s) def bar(s): return foo(s) * 2 def main(): bar('0') main() |
| 打印错误信息logging.exception(2) | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. # err.py: import logging def foo(s): return 10 / int(s) def bar(s): return foo(s) * 2 def main(): try: bar('0') except Exception as e: logging.exception(e) main() print('END') |
| raise 异常:抛出异常 | python #!/usr/bin/python # Write Python 3 code in this online editor and run it. def 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 bar() |
8.2、调试
| assert '错误提示' true跳过,false错误提示 py -O 文件名,让断言失效 | python def foo(s): n = int(s) assert n != 0, 'n is zero!' return 10 / n def main(): foo('0') |
|---|---|
| import logging logging.info(提示信息) | python import logging logging.basicConfig(level=logging.INFO) s = '0' n = int(s) logging.info('n = %d' % n) print(10 / n) |
| pdb 类似于debug 启动命令: plain python -m pdb err.py l:查看代码n:执行下一行代码 p 变量名:查看变量的值 | |
暂停,正常启用py 文件名python pdb.set_trace() # 运行到这里会自动暂停 | python # err.py import pdb s = '0' n = int(s) pdb.set_trace() # 运行到这里会自动暂停 print(10 / n) |
8.3、单元测试
| 导入单元测试:import unittest 继承单测:class TestDict(unittest.TestCase): 可以运行: python if __name__ == '__main__': unittest.main() 注意异常判断的写法:python with self.assertRaises(KeyError): value = d['empty'] | python class Dict(dict): def __init__(self, **kw): super().__init__(**kw) def __getattr__(self, key): try: return self[key] except KeyError: raise AttributeError(r"'Dict' object has no attribute '%s'" % key) def __setattr__(self, key, value): self[key] = value python import unittest from mydict import Dict class TestDict(unittest.TestCase): def test_init(self): d = Dict(a=1, b='test') self.assertEqual(d.a, 1) self.assertEqual(d.b, 'test') self.assertTrue(isinstance(d, dict)) def test_key(self): d = Dict() d['key'] = 'value' self.assertEqual(d.key, 'value') def test_attr(self): d = Dict() d.key = 'value' self.assertTrue('key' in d) self.assertEqual(d['key'], 'value') def test_keyerror(self): d = Dict() with self.assertRaises(KeyError): value = d['empty'] def test_attrerror(self): d = Dict() with self.assertRaises(AttributeError): value = d.empty def setUp(self): print('setUp...') def tearDown(self): print('tearDown...') if __name__ == '__main__': unittest.main() |
|---|
8.4、注释
| 单行注释:# 多行注释:""" """ | python class Student: """ 文档注释(多行注释):用来初始化 """ def __init__(self, name): # 单行注释 self._name = name |
|---|
8.5、文档测试
| 文档注释: """ """ 注释里面的内容会自动执行,并且与下一行的期望值对比,如果相同则通过否则报错 运行命令: py -m doctest 文件名 | python def add(a, b): """ 求和函数 >>> add(1,2) 3 >>> add(1,1) 2 """ return a+b; |
|---|
9、IO变成
9.1、文件读写
| 读 r 1. open('路径', r) f.close() 2. with open('路径', r) as f 3. 读取指定编码 4. 遇到错误忽略 | python try: f = open('D:/workspace/python/basic-grammar-learning/文档测试.py', 'r') # print(f.read()) finally: if f: f.close() # 上面的写法等价于下面的 with open('D:/workspace/python/basic-grammar-learning/文档测试.py', 'r') as f: # print(f.read()) # print(f.readline()) for line in f.readlines(): print(line) png = open('D:/Desktop/pic/其他/1.png', 'rb') print(png.read()) # 读取gbk编码 txt = open('D:/Desktop/test/1.txt', 'r', encoding='UTF-8') print(txt.read()) # 遇到错误忽略 error = open('D:/Desktop/test/1.txt', 'r', encoding='UTF-8', errors = 'ignore') print(txt.read()) |
|---|---|
| 写 w(文本)/wb(二进制文件) a(追加)/ab(追加二进制文件) 先写到内存缓存,有时间在真写,还有就是一定要调用close(),要不然可能没写进去 | python txt = open('D:/Desktop/test/1.txt', 'a') txt.write('hello world!') txt.close(); # 遇到错误忽略 error = open('D:/Desktop/test/1.txt', 'r') print(error.read()) error.close() |
9.2、StringIO和BytesIO
| StringIO:内存中写str from io import StringIO f = StringIO() f.write('hello') print(f.getvalue()) f2.readline() | python from io import StringIO f = StringIO() # 返回写入的长度 f.write('hello') f.write(' ') f.write('world!') print(f.getvalue()) f2 = StringIO('hello\nHI!\n Goodbye!') while True: s = f2.readline() if s == '': break print(s.strip()) |
|---|---|
| 内存中写二进制BytesIO from io import BytesIO b = BytesIO() b.write('中文'.encode('utf-8')) print(b.getvalue()) print(b2.read()) | python from io import BytesIO b = BytesIO() b.write('中文'.encode('utf-8')) print(b.getvalue()) b2 = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87') print(b2.read()) |
8.3、操作文件和目录
| 导入os | python import os # 操作系统 print(os.name) # 环境变量 print(os.environ) print(os.environ.get('PATH')) print(os.environ.get('PATH', 'default')) # 当前目录的绝对路径 print(os.path.abspath('.')) # 展示完整路径 print(os.path.join('D:\workspace\python\basic-grammar-learning', 'testdir')) # 创建一个目录 # os.mkdir('D:/workspace/python/basic-grammar-learning/testdir') # 删除一个目录 # os.rmdir('D:/workspace/python/basic-grammar-learning/testdir') # 拆分路径 print(os.path.split('D:/workspace/python/basic-grammar-learning/文档测试.py')) # 获取扩展名 print(os.path.splitext('D:/workspace/python/basic-grammar-learning/文档测试.py')) # 文件重命名 os.rename('文档注释.py', '文档注释test.py') #删除文件 # os.remove('文档注释test.py') |
|---|
9.4、序列化
| pickle序列化 dump、dumps load、loads | python import pickle d = dict(name='Bob', age=20, score=88) # 返回二进制文件 by = pickle.dumps(d) print(by) f = open('dump.txt', 'wb') pickle.dump(d, f) f.close() fr = open('dump.txt', 'rb') rd = pickle.load(fr) fr.close(); print(rd) print(pickle.loads(by)) |
|---|---|
| JSON序列化 json.dumps():序列化 json.loads():反序列化 类的序列话和反序列化需要手动写方法,并制定默认方法 | python import json d = dict(name='Bob', age=20, score=88) print(json.dumps(d)) json_str = '{"age": 20, "score": 88, "name": "Bob"}' print(json.loads(json_str)) 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 } def dict2student(d): # 把字典 d 转换成 Student 对象 return Student(d['name'], d['age'], d['score']) s = Student('Bob', 20, 88) print(json.dumps(s, default=Student.student2dict)) json_str = '{"name": "Bob", "age": 20, "score": 88}' ss = json.loads(json_str, object_hook=Student.dict2student) print(ss.name) |