运算符

  1. # 整除
  2. 17 // 3
  3. # 乘方
  4. 2 ** 7

字符串

r是raw的缩写,字符串不转移。
三引号字符串会包含换行,不想包含在行尾写 \

  1. r'a\a'
  2. """
  3. asd \
  4. """
  5. s = 'asd'
  6. # 重复
  7. s * 3
  8. s[:2]

切片

  1. +---+---+---+---+---+---+
  2. | P | y | t | h | o | n |
  3. +---+---+---+---+---+---+
  4. 0 1 2 3 4 5 6
  5. -6 -5 -4 -3 -2 -1

小于-len()和-len()作用一样

  1. s[-7:] == s[-6:]

global关键字

  1. g = 4
  2. def foo():
  3. global g
  4. g = 2
  5. foo()
  6. print(g)
  7. # 输出
  8. # 2

表达式

比较运算符

  1. #比较是否是一个对象,也就是id()函数返回是否相等。
  2. a = [1, 2]
  3. b = a
  4. print(a is b)
  5. print(a is not b)
  6. True
  7. False
  1. #值相等
  2. a = [1 ,2]
  3. b = [1, 2]
  4. print(a == b)
  5. print(a is b)
  6. True
  7. False

4 流程控制

4.1 if

  1. # 返回Goodbye
  2. "Hello" if 0 else "Goodbye"
  3. # 返回Hello
  4. "Hello" if 1 else "Goodbye"

4.6 函数

args和*kwargs

  1. def foo(*args, **kwargs):
  2. print(args)
  3. print(kwargs)
  4. foo(1, 2, x=3, y=4)
  5. #输出
  6. #(1, 2)
  7. #{'x': 3, 'y': 4}
  8. d = {'x': 3, 'y': 4}
  9. foo(**d)

装饰器(decorator)

一阶用法

  1. def log(fn):
  2. def wrapper(*args, **kwargs):
  3. print('called %s()' % fn.__name__)
  4. return fn(*args, **kwargs)
  5. return wrapper
  6. @log
  7. def say():
  8. print('haha')
  9. say()
  10. #输出
  11. #called say()
  12. #haha
  13. #等价于 say = log(say)

二阶用法

  1. def log(text):
  2. def decorator(fn):
  3. def wrapper(*args, **kwargs):
  4. print('%s %s' % (text, fn.__name__))
  5. return fn(*args, **kwargs)
  6. return wrapper
  7. return decorator
  8. @log('execute')
  9. def say():
  10. print('haha')
  11. say()
  12. #输出
  13. #execute say
  14. #haha
  15. #等价于 say = log('execute')(say)

双下函数

如果没有实现 repr,当我们在控制台里打印一个向量的实例时,得到的字符串 可能会是 。
bool(x) 的背后是调用 x.bool() 的结果;如果不存在 bool 方法,那么 bool(x) 会 尝试调用 x.len()。若返回 0,则 bool 会返回 False;否则返回 True。
seq[start:stop:step] 进行求值的时候,Python 会调用 seq.getitem(slice(start, stop, step))。

双下函数的思想有点类似其他语言里的interface和trait

5 数据结构

5.3 元组

  1. # 单元元素元组
  2. tup1 = (1,)
  3. tup2 = (3, 4)
  4. new_tup = t1 + t2

5.4 集合

5.5 字典

初始化

  1. author = { 'id': 1 }
  2. author = dict(id=1)
  3. #注意容易出错
  4. key = 'id'
  5. author = { key : 1} # {'id': 1}
  6. author = dict(key = 1) # {'key': 1}

取值

  1. author['name'] #KeyError
  2. author.get('name') #None

遍历

迭代器

  1. for k in d:
  2. print(k)
  3. for k, v in d.items():
  4. print(k, v)

*进阶用法

解构

列表里的元组、字典都可以解构。

  1. d = {'x': 1, 'y': 2, 'z': 3}
  2. for k, v in d.items():
  3. print(k, v)
  4. # 输出
  5. # x 1
  6. # y 2
  7. # z 3
  8. for x, y, z in [(1, 2, 3), (4, 5, 6)]:
  9. print(x, y, z)
  10. # 输出
  11. # 1 2 3
  12. # 4 5 6
  13. def foo(**kwargs):
  14. print(kwargs)
  15. #形式参数必须和字典的key一一对应
  16. def bar(x, y):
  17. print(x, y)
  18. d = {'x': 1, 'y': 2}
  19. foo(**d)
  20. bar(**d)
  21. #输出
  22. #{'x': 1, 'y': 2}
  23. #1 2
  24. # 字典合并
  25. dm = {**d1, **d2}

6 模块

  1. import sound.effects.echo
  2. sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

使用from可以不使用包前缀

  1. from sound.effects import echo
  2. echo.echofilter(input, output, delay=0.7, atten=4)
  1. import subpackage1.a # 将模块subpackage.a导入全局命名空间,例如访问a中属性时用subpackage1.a.attr
  2. from subpackage1 import a # 将模块a导入全局命名空间,例如访问a中属性时用a.attr_a
  3. from subpackage.a import attr_a # 将模块a的属性直接导入到命名空间中,例如访问a中属性时直接用attr_a

模块导入优先级
系统包 > 同目录 > sys.path

绝对路径

from foo.bar import haha

相对路径

from .foo import bar
.当前模块 ..上层模块 …上上层,以此类推。

报错解决

ValueError: attempted relative import beyond top-level package

6.4 包

init.py

init.py 里面可以写import时执行的代码
all设置后import * 只会导入指定模块

  1. __all__ = ["echo", "surround", "reverse"]
  2. from sound.effects import *


8 错误和异常

把try中没必要的代码放到else里

  1. try:
  2. raise ValueError('a')
  3. except ValueError as e:
  4. print(e)
  5. except Exception as e:
  6. print('e' + e)
  7. else:
  8. print('haha')

9 类

继承

  1. class Base:
  2. pass
  3. class Foo(Base):
  4. def __init__():
  5. super().__init__():
  6. #类属性
  7. bar = 123
  8. # 菱形继承会调用多重,super则不会
  9. class Bar(Base):
  10. def __init__():
  11. Base.__init__(self)

MRO列表

  1. Foo.__mro__

new

9.8 迭代器

在函数参数中复制传值传递,既函数内迭代器状态变化不会影响作用域外。

9.9 生成器

执行生成器函数返回迭代器

  1. def reverse(data):
  2. for index in range(len(data)-1, -1, -1):
  3. yield data[index]
  4. for char in reverse('golf'):
  5. print(char)

9.10 生成器表达式

节省内存,不会生成真正的列表。

  1. for tshirt in ('%s %s' % (c, s) for c in colors for s in sizes):
  2. print(tshirt)

classmethod和staticmethod

对多态支持不同。

  1. class Foo:
  2. @classmethod
  3. def class_bar(cls):
  4. pass
  5. @staticmethod
  6. def static_bar():
  7. pass

https://www.zhihu.com/question/20021164

复合语句

with

  1. class Foo:
  2. def __enter__(self):
  3. print('into enter')
  4. return self
  5. def __exit__(self, exc_type, exc_val, exc_tb):
  6. print(exc_type, exc_val, exc_tb)
  7. print('into exit')
  8. def run(self):
  9. raise Exception('hehe')
  10. with Foo() as f:
  11. f.run()

as 后面的变量是 enter()的返回值。