基于 Learn X in Y minutes 进行修改

注释

  1. # 单行注释: 用井字符开头
  2. # 多行注释: 需要用 3 个双引号或者单引号包裹
  3. """
  4. 多行字符串用三个引号包裹
  5. 也常被用来做多行注释
  6. 可以是单引号, 也可以是双引号
  7. 注意, 必须是英文符号
  8. """
  9. # 在调试代码时, 经常把某一部分代码注释掉, 来临时跳过某些代码, 进行对比测试

数据类型

  1. # Python的数据类型:
  2. # 整数 int
  3. # 浮点数 float
  4. # 字符串 str
  5. # 布尔值 bool
  6. # 数组 array
  7. # 元组 turple
  8. # 字典 dict
  9. # 集合 set
  10. # 空对象 None
  11. # 用来获取数据类型的函数
  12. type()
  13. # 整数 integer
  14. 3 # → 3
  15. type(3) # → <class 'int'>
  16. a = int(input('请输入数字')) # 想要获取输入的数字, 记得要转化一下
  17. # 浮点数 float
  18. 1.0 # → 1.0
  19. type(1.0) # → <class 'float'>
  20. # 布尔值 boolean
  21. True # 注意, True 和 False 都必须是首字母大写
  22. False
  23. type(True) # → <class 'bool'>
  24. # 整数也可以当作布尔值
  25. 0 and 2 # → 0
  26. -5 or 0 # → -5
  27. 0 == False # → True
  28. 2 == True # → False
  29. 1 == True # → True
  30. # 这些值都算是 False: None、0、空字符串、空列表、空字典
  31. # 而其他的所有的值都是 True
  32. # 注意, 没有所谓空集合, 因为空集合就是空字典 {}
  33. bool(0) # → False
  34. bool("") # → False
  35. bool([]) # → False
  36. bool({}) # → False
  37. # 字符串 string
  38. type("Hello World") # → <class 'str'>
  39. # 字符串用单引号或者双引号都可以
  40. "这是个字符串"
  41. '这也是个字符串'
  42. # 字符串可以被当作列表
  43. "This is a string"[0] # → 'T'
  44. # 列表 list
  45. li = []
  46. type(li) # → <class 'list'>
  47. # 元组 tuple
  48. # 元组是不可改变的序列
  49. tup = (1, 2, 3)
  50. type(tup) # → <class 'tuple'>
  51. tup[0] # → 1
  52. tup[0] = 3 # 抛出TypeError, 因为元组不能被修改
  53. # 字典 dictionary
  54. empty_dict = {}
  55. type(empty_dict) # → <class 'dict'>
  56. # 字典的初始化
  57. filled_dict = {"one": 1, "two": 2, "three": 3}
  58. # 集合 set
  59. empty_set = set()
  60. type(empty_set) # → <class 'set'>
  61. # 初始化一个集合, 和字典的初始化相似
  62. some_set = {1, 1, 2, 2, 3, 4} # some_set现在是{1, 2, 3, 4}
  63. # None是一个对象
  64. None # → None

变量

  1. # 在变量赋值前, 不用提前声明变量
  2. # 变量名用数字、字母、下划线组成, 但是数字不能放在变量名的第1位
  3. # 变量名对大小写敏感, 也就是说 thisName 不等于 thisname
  4. # 建议变量命名使用小写字母, 然后用下划线来分隔
  5. some_var = 5
  6. some_var # → 5
  7. # 变量命名也可以包含数字, 但是数字不能放在命名的第 1 位
  8. 4some_var # 报错, SyntaxError: invalid syntax
  9. # 访问未赋值的变量会抛出异常
  10. # 参考教程后面“流程控制:异常”的部分, 来学习异常处理
  11. some_unknown_var # 抛出NameError
  12. # 全局变量
  13. global some_var

操作符

操作符: 算术操作符

“操作符”的英文名是 Operator, 也称为“运算符”, 包括算术运算、比较运算、逻辑运算… 但是, 我建议用“操作符”来指称, 而不要用“运算符”来指称.

这是因为“运算”这个词给我们的心理暗示是数学上的加减乘除运算, 我们直观上不会认为比较操作、逻辑操作是一种运算 ( 尽管对于计算机来说, 的确是运算 ), 因此大脑面对“比较运算”和“逻辑运算”这些词的时候会产生不协调感. 而“操作符”是一种中性的表述, “操作”可以包括算术运算、比较、逻辑判断…

  1. # Python 中的算术和我们在学校学的算数没有太大区别
  2. 1 + 1 # → 2
  3. 8 - 1 # → 7
  4. 10 * 2 # → 20
  5. # “除法”例外, 除法的结果会自动转换成浮点数
  6. 35 / 5 # → 7.0
  7. 5 / 3 # → 1.6666666666666667
  8. -5 / 3 # → -1.6666666666666667
  9. # 两个斜杠//的叫“整数除法”, 需要向下取整
  10. # 本质是 floor 操作, floor = 地板, 也就是说取接近计算结果最近的那个整数
  11. 5 // 3 # → 1
  12. 5.0 // 3.0 # → 1.0 # 浮点数也可以进行整数除法
  13. -5 // 3 # → -2 # 注意这里! 记住, 整数除法的结果都是向下取整, 也就是往小的取整
  14. -5.0 // 3.0 # → -2.0
  15. # 如果想要截取除法结果的整数部分, 需要使用 math 模块的 trunc 函数
  16. import math
  17. math.trunc(1 / 2) # → 0
  18. math.trunc(-5 / 3) # → -1
  19. # 浮点数的运算结果也是浮点数
  20. 3 * 2.0 # → 6.0
  21. # 取余数, 也叫“取模”、“模除”
  22. 7 % 3 # → 1
  23. # x 的 y 次方
  24. 2**4 # → 16
  25. 3**2 # → 9
  26. # 平方
  27. 5**2 # → 25
  28. 9**2 # → 81

操作符: 逻辑操作符

  1. # 布尔值
  2. True
  3. False
  4. # 逻辑操作符, 注意 and 和 or 都是小写
  5. True and False # → False
  6. False or True # → True
  7. # 逻辑操作符, 用 not 取非
  8. not True # → False
  9. not False # → True
  10. # 整数也可以当作布尔值
  11. 0 and 2 # → 0
  12. -5 or 0 # → -5
  13. 0 == False # → True
  14. 2 == True # → False
  15. 1 == True # → True

操作符: 比较操作符

  1. # 比较大小
  2. 1 < 10 # → True
  3. 1 > 10 # → False
  4. 2 <= 2 # → True
  5. 2 >= 2 # → True
  6. # 用 == 判断是否相等
  7. 1 == 1 # → True
  8. 2 == 1 # → False
  9. 3 = 2 # → 会报错, 因为 = 是表示赋值, == 才是判断是否相等
  10. # 用 != 判断是否不等于
  11. 1 != 1 # → False
  12. 2 != 1 # → True
  13. # 大小比较可以连起来!
  14. 1 < 2 < 3 # → True
  15. 2 < 3 < 2 # → False
  16. # 当与None进行比较时, 不要用 ==
  17. # 要用 is
  18. # is 是用来比较两个变量是否指向同一个对象
  19. "etc" is None # → False
  20. None is None # → True

操作符: 字符串的操作符

  1. # 用加号连接字符串
  2. "Hello " + "world!" # → "Hello world!"

操作符: 列表的操作符

  1. # 用 + 和空格来拼接列表
  2. [1, 2, 3] + ['hello', 'python'] # → [1, 2, 3, 'hello', 'python']
  3. # 用 * 来拷贝列表
  4. [1, 2, 3]*3 # → [1, 2, 3, 1, 2, 3, 1, 2, 3]
  5. # 列表也有逻辑操作
  6. # ==、!=、<、<=、>、>=、in、not in
  7. # 将两个列表中的元素逐个拿出来比较
  8. # 遵循字符串比较相同的规则 -- 一旦决出胜负, 即刻停止, 不用再比较后面的元素
  9. # in、not in 是用来判断元素是否在列表中的逻辑操作
  10. a_list = [1, 2, 3]
  11. b_list = [8]
  12. c_list = [1, 4, 3]
  13. a_list > b_list # → False
  14. a_list < b_list # → False
  15. a_list < c_list # → True

操作符: 优先级

  1. # 和学校学的算数一样, 乘除的优先级高于加减, 括号决定了计算的优先级
  2. 1 + 3 * 2 # → 7
  3. (1 + 3) * 2 # → 8

容器

列表的操作

  1. # 用列表(list)储存序列
  2. li = []
  3. # 创建列表时也可以同时赋给元素
  4. other_li = [4, 5, 6]
  5. # 用append在列表最后追加元素
  6. li.append(1) # li 现在是[1]
  7. li.append(2) # li 现在是[1, 2]
  8. li.append(4) # li 现在是[1, 2, 4]
  9. li.append(3) # li 现在是[1, 2, 4, 3]
  10. # 用pop从列表尾部删除,并获得这个尾部的元素
  11. li.pop() # → 3 且 li 现在是[1, 2, 4]
  12. # 把3再放回去
  13. li.append(3) # li 变回[1, 2, 4, 3]
  14. # 列表存取跟数组一样
  15. li[0] # → 1
  16. # 取出最后一个元素
  17. li[-1] # → 3
  18. # 越界存取会造成IndexError
  19. li[4] # 抛出IndexError
  20. # 列表可以切片
  21. # 注意, 切片是从第1个参数指示的索引位置开始, 在第2个参数指示的索引位置之前就结束
  22. # 所以, 下面的切片只取了第 1、2 个索引位置上的数
  23. li[1:3] # → [2, 4]
  24. # 取尾
  25. li[2:] # → [4, 3]
  26. # 取头
  27. li[:3] # → [1, 2, 4]
  28. # 隔一个取一个, 也就是步长为 2. 注意, 原有列表的值不变
  29. li[::2] # →[1, 4]
  30. # 倒序排列, 也就是步长为 -1. 注意, 原有列表的值不变
  31. li[::-1] # → [3, 4, 2, 1]
  32. # 可以用三个参数的任何组合来构建切片
  33. # li[始:终:步伐]
  34. # 用del删除任何一个元素
  35. del li[2] # li 现在是 [1, 2, 3]
  36. # 列表可以相加
  37. # 注意: li 和 other_li的值都不变
  38. li + other_li # → [1, 2, 3, 4, 5, 6]
  39. # 可以操作符 + 来拼接列表
  40. li + other_li # li现在是[1, 2, 3, 4, 5, 6]
  41. # 也可以用 extend 拼接列表
  42. li.extend(other_li) # li现在是[1, 2, 3, 4, 5, 6]
  43. # 用in测试列表是否包含值
  44. 1 in li # → True
  45. # 用len取列表长度
  46. len(li) # → 6

元组的操作

  1. # 元组是不可改变的序列
  2. tup = (1, 2, 3)
  3. tup[0] # → 1
  4. tup[0] = 3 # 报错, TypeError, 因为元组不能被修改
  5. # 列表允许的操作, 元组大部分都可以使用
  6. len(tup) # → 3
  7. tup + (4, 5, 6) # → (1, 2, 3, 4, 5, 6)
  8. tup[:2] # → (1, 2)
  9. 2 in tup # → True
  10. # 可以把元组合列表解包, 赋值给变量
  11. a, b, c = (1, 2, 3) # 现在a是1, b是2, c是3
  12. # 元组周围的括号是可以省略的
  13. d, e, f = 4, 5, 6
  14. # 交换两个变量的值就这么简单
  15. e, d = d, e # 现在d是5, e是4

字典的操作

  1. # 用字典表达映射关系
  2. empty_dict = {}
  3. # 字典的初始化
  4. filled_dict = {"one": 1, "two": 2, "three": 3}
  5. # 用[]取值
  6. filled_dict["one"] # → 1
  7. # 用 keys 可以获得该字典所有的键
  8. # 因为 keys 返回的是一个可迭代对象, 所以在这里把结果包在 list 里
  9. # 注意: 和列表不同, 字典的键的顺序是不定的, 你得到的结果可能和下面不一样
  10. list(filled_dict.keys()) # → ["three", "two", "one"]
  11. # 用 values 可以获得所有的值. 跟keys一样, 这里用list包起来, 顺序也可能不同
  12. list(filled_dict.values()) # → [3, 2, 1]
  13. # 用 in 测试一个字典是否包含一个键
  14. "one" in filled_dict # → True
  15. 1 in filled_dict # → False
  16. # 访问不存在的键会导致 KeyError
  17. filled_dict["four"] # KeyError
  18. # 用 get 来避免 KeyError
  19. filled_dict.get("one") # → 1
  20. filled_dict.get("four") # → None
  21. # 当键不存在的时候, get方法可以返回默认值
  22. filled_dict.get("one", 4) # → 1
  23. filled_dict.get("four", 4) # → 4
  24. # setdefault 方法只有当键不存在的时候插入新值
  25. filled_dict.setdefault("five", 5) # filled_dict["five"]设为5
  26. filled_dict.setdefault("five", 6) # filled_dict["five"]还是5
  27. # 字典赋值
  28. filled_dict.update({"four":4}) # → {"one": 1, "two": 2, "three": 3, "four": 4}
  29. filled_dict["four"] = 4 # 另一种赋值方法
  30. # 用 del 删除键值对
  31. del filled_dict["one"] # 从 filled_dict 中把 "one": 1 的键值对删除

集合的操作

  1. # 用set表达集合
  2. empty_set = set()
  3. # 初始化一个集合, 和字典的初始化相似
  4. some_set = {1, 1, 2, 2, 3, 4} # some_set现在是{1, 2, 3, 4}
  5. # 可以把集合赋值给变量
  6. filled_set = some_set
  7. # 向集合添加元素
  8. filled_set.add(5) # filled_set现在是{1, 2, 3, 4, 5}
  9. # 用 & 取集合的交集
  10. other_set = {3, 4, 5, 6}
  11. filled_set & other_set # → {3, 4, 5}
  12. # 用 | 取集合的并集
  13. filled_set | other_set # → {1, 2, 3, 4, 5, 6}
  14. # 用 - 取集合的补集
  15. {1, 2, 3, 4} - {2, 3, 5} # → {1, 4}
  16. # 用 in 测试集合中是否包含某元素
  17. 2 in filled_set # → True
  18. 10 in filled_set # → False

输入输出

获取输入

  1. # 获取用户输入的内容
  2. a = input('请输入你的名字')
  3. b = input('请输入你的年龄')
  4. print("Welcome {name}! Your age is {age}.".format(name=a, age=b))

格式化输出

  1. # print是内置的打印函数
  2. print("Hello World!") # → Hello World!
  3. a = 'you'
  4. b = 'me'
  5. print(a, 'and', b, '.') # → you and me .
  6. print(a, ' and ', b, '.', sep='', end='\n') # → you and me.
  7. # 用.format来格式化字符串
  8. "{} can be {}".format("strings", "interpolated")
  9. # 可以重复使用相同的参数
  10. "我喜欢{0}, 爸爸也喜欢{0}, 妈妈喜欢{1}".format("苹果", "梨")
  11. # → "我喜欢苹果, 爸爸也喜欢苹果, 妈妈喜欢梨"
  12. # 如果不想数参数, 可以用关键字
  13. "{name} wants to eat {food}".format(name="Bob", food="lasagna")
  14. # → "Bob wants to eat lasagna"
  15. # 如果要输出多行字符串, 除了写一条一条语句之外, 还可以
  16. message = """Hello, {name}
  17. Sincerely, {me}"""
  18. print (message.format(name = "Jake", me = "Sally"))
  19. # 输出:
  20. # Hello, Jake
  21. # Sincerely, Sally
  22. # 如果你的Python3程序也要在Python2.5以下环境运行
  23. # 也可以用老式的格式化语法
  24. # %s 表示string字符串, %d 表示digit数字, %f 表示float浮点数
  25. "%s can be %s the %s way" % ("strings", "interpolated", "old")

流程控制

流程控制: 判断

  1. # 注意 "elif" 的写法, 它表示 else if
  2. some_var = 5
  3. if some_var > 10: #定义一个判断条件
  4. print("some_var 比 10 大")
  5. elif some_var < 10: # elif是可选的
  6. print("some_var 比 10 小")
  7. else: # else也是可选的
  8. print("some_var 和 10 相等")

流程控制: 循环

  1. # 有 2 种循环:
  2. # - for 循环
  3. # - while 循环
  4. # for循环
  5. # 用for循环遍历列表
  6. for friends in ["李雷", "韩梅梅", "张华", "李萍"]:
  7. print("{}是我的朋友".format(friends))
  8. # 打印结果:
  9. """
  10. 李雷是我的朋友
  11. 韩梅梅是我的朋友
  12. 张华是我的朋友
  13. 李萍是我的朋友
  14. """
  15. # range 函数
  16. # 用 range 函数生成列表, 用于for循环的迭代
  17. for i in range(4):
  18. print(i)
  19. # 打印结果:
  20. """
  21. 0
  22. 1
  23. 2
  24. 3
  25. """
  26. for i in range(1,7,2): # range(起始, 结尾, 步长), 注意, 切片在声明的结尾之前就结束了
  27. print(i)
  28. # 打印结果:
  29. """
  30. 1
  31. 3
  32. 5
  33. """
  34. # 注意, 上面的打印结果中没有 7, 因为在 7 之前就结束了
  35. # while 循环
  36. x = 0
  37. while x < 4:
  38. print(x)
  39. x += 1 # x = x + 1 的简写
  40. # 打印结果:
  41. """
  42. 0
  43. 1
  44. 2
  45. 3
  46. """

流程控制: 异常

  1. # 用 try/except 来处理“异常”, 也就是通常理解的“错误”
  2. try:
  3. raise IndexError("This is an index error") # 用raise抛出异常
  4. except IndexError as e:
  5. pass # pass是无操作, 但是应该在这里处理错误
  6. except (TypeError, NameError): # 可以同时处理不同类的错误
  7. pass
  8. else: # else 语句是可选的, 必须在所有的except之后
  9. print("All good!") # 只有当try运行完没有错误的时候这句才会运行

可迭代对象

可迭代(iterable)的对象可以作为序列的对象, 比如上面的 range() 函数返回的对象就是可迭代的

  1. filled_dict = {"one": 1, "two": 2, "three": 3}
  2. our_iterable = filled_dict.keys()
  3. print(our_iterable) # → dict_keys(['one', 'two', 'three']), 是一个可迭代对象
  4. # 可迭代的对象可以遍历
  5. for i in our_iterable:
  6. print(i) # 打印 one, two, three
  7. # 但是不可以随机访问
  8. our_iterable[1] # 报错, 抛出TypeError
  9. # 可迭代对象知道怎么生成迭代器
  10. our_iterator = iter(our_iterable)
  11. # 迭代器是一个可以记住遍历的位置的对象
  12. # 用 __next__ 可以取得下一个元素
  13. our_iterator.__next__() # → "one"
  14. # 再一次调取__next__时会记得上一次的位置
  15. our_iterator.__next__() # → "two"
  16. our_iterator.__next__() # → "three"
  17. # 当迭代器所有元素都取出后, 会抛出StopIteration
  18. our_iterator.__next__() # 抛出StopIteration
  19. # 可以用list一次取出迭代器所有的元素
  20. list(filled_dict.keys()) # → Returns ["one", "two", "three"]

组织代码

组织代码: 函数

  1. # 定义函数
  2. def add(x, y):
  3. print("x is {} and y is {}".format(x, y))
  4. return x + y # 用return语句返回
  5. # 调用函数
  6. add(5, 6) # → 印出"x is 5 and y is 6"并且返回11
  7. # 也可以用关键字参数来调用函数
  8. add(y=6, x=5) # 关键字参数可以用任何顺序
  9. add(x=5, y=6)
  10. # 可变参数
  11. # 我们可以定义一个可变参数的函数, 即参数数量不用写死
  12. def varargs(*args):
  13. return args
  14. varargs(1, 2, 3) # → (1, 2, 3)
  15. varargs(1, 2, 3, 4) # → (1, 2, 3, 4)
  16. # 我们也可以定义一个关键字可变参数的函数
  17. def keyword_args(**kwargs):
  18. return kwargs
  19. keyword_args(big="foot", loch="ness") # → {"big": "foot", "loch": "ness"}
  20. # 这两种可变参数可以混着用
  21. def all_the_args(*args, **kwargs):
  22. print(args)
  23. print(kwargs)
  24. all_the_args(1, 2, a=3, b=4)
  25. # 输出:
  26. """
  27. (1, 2)
  28. {'a': 3, 'b': 4}
  29. """
  30. # 调用可变参数函数时可以做跟上面相反的, 用*展开序列, 用**展开字典
  31. args = (1, 2, 3, 4)
  32. kwargs = {"a": 3, "b": 4}
  33. all_the_args(*args) # 相当于 all_the_args(1, 2, 3, 4)
  34. all_the_args(**kwargs) # 相当于 all_the_args(a=3, b=4)
  35. all_the_args(*args, **kwargs) # 相当于 all_the_args(1, 2, 3, 4, a=3, b=4)
  36. # 函数的作用域
  37. x = 5
  38. def setLocalX(num):
  39. x = num # → 43, 这是局部作用域的 x, 和全局作用域的 x 不同
  40. print (x) # → 43
  41. def setGlobalX(num):
  42. global x # 声明为为全局变量
  43. print (x) # → 5
  44. x = num # 全局作用域的 x 的赋值被修改
  45. print (x) # → 6
  46. setLocalX(43) # 输出 43
  47. setGlobalX(6) # 输出 5 6
  48. # 函数在 Python 中是一等公民
  49. def create_adder(x):
  50. def adder(y):
  51. return x + y
  52. return adder
  53. add_10 = create_adder(10)
  54. add_10(3) # → 13
  55. # 匿名函数
  56. # 可以用 lambda 关键字来写匿名函数, 可以让函数的代码非常简洁
  57. # 通常的函数写法:
  58. def compare (x):
  59. return x >2
  60. compare (3) # → True
  61. # lambada 匿名函数的写法:
  62. compare = lambda x : x>2
  63. compare(3) # → True
  64. # 内置的高阶函数
  65. map(add_10, [1, 2, 3]) # → [11, 12, 13]
  66. filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # → [6, 7]
  67. # 用列表推导式可以简化映射和过滤. 列表推导式的返回值是另一个列表
  68. [add_10(i) for i in [1, 2, 3]] # → [11, 12, 13]
  69. [x for x in [3, 4, 5, 6, 7] if x > 5] # → [6, 7]

组织代码: 类

  1. # 定义一个继承object的类
  2. class Human(object):
  3. # 类的属性, 被所有此类的实例共用.
  4. species = "H. sapiens"
  5. # 构造方法, 当有实例被初始化时, 就会被调用
  6. # 名字前后的双下划线, 表明这个属性或者方法对Python有特殊意义
  7. # 通常我们自己定义的名字不应该以下划线开头
  8. def __init__(self, name):
  9. # 将参数赋值给实例的属性
  10. self.name = name
  11. # 实例的方法, 第一个参数总是self, 就是这个实例对象
  12. def say(self, msg):
  13. return "{name}: {message}".format(name=self.name, message=msg)
  14. # 类方法, 被所有此类的实例共用. 第一个参数是这个类对象
  15. @classmethod
  16. def get_species(cls):
  17. return cls.species
  18. # 静态方法. 调用时没有实例或类的绑定
  19. @staticmethod
  20. def grunt():
  21. return "*grunt*"
  22. # 构造一个实例
  23. i = Human(name="Ian")
  24. print(i.say("hi")) # → "Ian: hi"
  25. j = Human("Joel")
  26. print(j.say("hello")) # → "Joel: hello"
  27. # 调用一个类方法
  28. i.get_species() # → "H. sapiens"
  29. # 改一个共用的类属性
  30. Human.species = "H. neanderthalensis"
  31. i.get_species() # → "H. neanderthalensis"
  32. j.get_species() # → "H. neanderthalensis"
  33. # 调用静态方法
  34. Human.grunt() # → "*grunt*"

组织代码: 模块

  1. # 用import导入模块
  2. import math # 导入math数学模块, 才能调用开平方的 sqrt() 方法
  3. print(math.sqrt(16)) # → 4.0
  4. # 也可以从模块中导入指定的方法
  5. from math import ceil, floor
  6. print(ceil(3.7)) # → 4.0; 调用的时候, 只要写成 ceil(), 不用写成 math.ceil()
  7. print(floor(3.7)) # → 3.0
  8. # 你可以这样列出一个模块里所有的值
  9. import math
  10. dir(math)
  11. # 可以导入一个模块中所有值
  12. # 警告: 不建议这么做
  13. from math import *
  14. # 可以为模块设置别名
  15. import math as m
  16. math.sqrt(16) == m.sqrt(16) # → True
  17. # Python 模块的本质就是一个 Python 文件, import 就相当于导入这个文件
  18. # 我们可以自己写一个 Python 文件, 然后将其作为模块导入
  19. # 模块的名称就是文件的名字

高阶用法: 生成器 & 装饰器

  1. # 生成器(generators)
  2. # 用生成器可以方便地写惰性运算
  3. def double_numbers(iterable):
  4. for i in iterable:
  5. yield i + i
  6. # 生成器只有在需要时才计算下一个值
  7. # 它们每一次循环只生成一个值, 而不是把所有的值全部算好
  8. # range的返回值也是一个生成器
  9. # 不然一个1到900000000的列表会花很多时间和内存
  10. # 如果你想用一个Python的关键字当作变量名, 可以加一个下划线来区分
  11. range_ = range(1, 900000000)
  12. # 当找到一个 >=30 的结果就会停
  13. # 这意味着 `double_numbers` 不会生成大于30的数
  14. for i in double_numbers(range_):
  15. print(i)
  16. if i >= 30:
  17. break
  18. # 装饰器(decorators)
  19. # 下面这个例子中, beg装饰say
  20. # beg会先调用say. 如果返回的say_please为真, beg会改变返回的字符串
  21. from functools import wraps
  22. def beg(target_function):
  23. @wraps(target_function)
  24. def wrapper(*args, **kwargs):
  25. msg, say_please = target_function(*args, **kwargs)
  26. if say_please:
  27. return "{} {}".format(msg, "Please! I am poor :(")
  28. return msg
  29. return wrapper
  30. @beg
  31. def say(say_please=False):
  32. msg = "Can you buy me a beer?"
  33. return msg, say_please
  34. print(say()) # Can you buy me a beer?
  35. print(say(say_please=True)) # Can you buy me a beer? Please! I am poor :(