python的函数参数传递都是引用,所以在函数内部会改变原来的参数值。

  1. def desc_pet(names):
  2. names[0] = "what?"
  3. names = ["dog", "cat", "eagle"]
  4. desc_pet(names)
  5. print(names)
  6. --
  7. ['what?', 'cat', 'eagle']

函数参数:5种

必选参数和默认参数就不用多说了,主要介绍可变参数和关键字参数以及命名关键字参数。

  1. def desc_pet(animal_type, animal_name):
  2. print("\n I have a " + animal_type + ".")
  3. print("it's name is " + animal_name + ".")
  4. desc_pet("dog", "wangwang")
  5. desc_pet(animal_name="miaomiao", animal_type="cat")
  6. --
  7. I have a dog.
  8. it's name is wangwang.
  9. I have a cat.
  10. it's name is miaomiao.

可变参数

  1. ###### *作为形参 ######
  2. # *numbers中的星号让python创建一个名为nubmers的空元组,
  3. # 并将收到的所有值都封装到这个元组中
  4. def calc(*numbers):
  5. """caculate number"""
  6. print("numbers:", numbers)
  7. sum = 0
  8. for n in numbers:
  9. sum = sum + n * n
  10. return sum
  11. >>> calc()
  12. numbers: ()
  13. 0
  14. >>> calc(1,2)
  15. numbers: (1, 2)
  16. 5
  17. # 同样,我们可以传一个list或tuple
  18. >>> nums=[1,2,3]
  19. >>> calc(*nums)
  20. numbers: (1, 2, 3)
  21. 14
  22. >>> calc(nums)
  23. numbers: ([1, 2, 3],)
  24. Traceback (most recent call last):
  25. File "<stdin>", line 1, in <module>
  26. File "<stdin>", line 6, in calc
  27. TypeError: can't multiply sequence by non-int of type 'list'
  28. # 也可以与其他参数混用
  29. >>> def test(a, b, *arg):
  30. ... print(a,b, arg)
  31. ...
  32. >>> test(1, 2, 3, 4)
  33. (1, 2, (3, 4))
  34. >>> test(1, 2, 3)
  35. (1, 2, (3,))
  36. ###### *作为实参 ######
  37. >>> def f(a, b, c):
  38. ... print(a, b, c)
  39. ...
  40. >>> f(1, 2, 3)
  41. 1 2 3
  42. >>> l = [1, 2, 3]
  43. >>> f(*l)
  44. 1 2 3
  45. # 再看几种情况
  46. # 1. l是list时,*l是错误语法
  47. >>> *l
  48. File "<stdin>", line 1
  49. SyntaxError: can't use starred expression here
  50. # 2. 这样是直接传递一个参数,该参数是一个list
  51. >>> f(l)
  52. Traceback (most recent call last):
  53. File "<stdin>", line 1, in <module>
  54. TypeError: f() missing 2 required positional arguments: 'b' and 'c'
  55. # 3. 参数传多了
  56. >>> f(*[1,2,3,4])
  57. Traceback (most recent call last):
  58. File "<stdin>", line 1, in <module>
  59. TypeError: f() takes 3 positional arguments but 4 were given

关键字参数

  1. # **kw中的星号让python创建一个名为kw的空字典,
  2. # 并将收到的所有key-value对都封装到这个字典中。
  3. def person(name, age, **kw):
  4. print('name:', name, 'age:', age, 'other:', kw)
  5. >>> person('Michael', 30)
  6. name: Michael age: 30 other: {}
  7. >>> person('Adam', 45, gender='M', job='Engineer')
  8. name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
  9. >>> extra = {'city': 'Beijing', 'job': 'Engineer'}
  10. >>> person('Jack', 24, **extra)
  11. name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
  12. ###### ** 作为实参 ######
  13. >>> def f(a, b, c):
  14. ... print(a, b, c)
  15. ...
  16. >>> d={'b':2, 'c':3}
  17. >>> f(1, **d)
  18. 1 2 3
  19. >>> e = {'b':2, 'd':4}
  20. >>> f(1, e)
  21. Traceback (most recent call last):
  22. File "<stdin>", line 1, in <module>
  23. TypeError: f() missing 1 required positional argument: 'c'

命名关键字参数

  1. # 只接收city 和 job 作为关键字参数
  2. def person(name, age, *, city, job):
  3. print(name, age, city, job)
  4. >>> person('Jack', 24, city='Beijing', job='Engineer')
  5. Jack 24 Beijing Engineer
  6. >>> person(age=24, name='Jack', city='Beijing', job='Engineer')
  7. Jack 24 Beijing Engineer
  8. >>> person('Jack', 24, 'Beijing', 'Engineer')
  9. Traceback (most recent call last):
  10. File "<stdin>", line 1, in <module>
  11. TypeError: person() takes 2 positional arguments but 4 were given
  12. # 第二种方式,可变参数后的参数,默认为命名关键字参数
  13. def person(name, age, *args, city, job):
  14. print(name, age, args, city, job)
  15. >>> person('Jack', 24, 'Beijing', 'Engineer')
  16. Traceback (most recent call last):
  17. File "<stdin>", line 1, in <module>
  18. TypeError: person() takes 2 positional arguments but 4 were given

回调函数

例如A是一个函数,他自身作为一个参数,传递给B,在B里被调用,那么A就叫做回调函数,B叫做中间函数。
简单示例如下:

  1. # 回调函数1
  2. def f1(x):
  3. return x+2
  4. # 回调函数2
  5. def f2(x):
  6. return x+1
  7. # 中间函数,接受一个函数作为参数
  8. def addANumber(f, x):
  9. return 1 + f(x)
  10. # main成为起始函数,也就是调用中间函数的函数
  11. def main():
  12. i = addANumber(f1, 1)
  13. i = addANumber(f2, 1)
  14. if __name__ == "__main__":
  15. main()

内置函数

map

map需要两个参数,一个函数,一个列表,map会把函数依次作用在列表上,并返回一个列表。

  1. >>> def f(x):
  2. ... return x * x
  3. ...
  4. >>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
  5. [1, 4, 9, 16, 25, 36, 49, 64, 81]

reduce

再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3…]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。

  1. reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
  1. >>> def add(x, y):
  2. ... return x + y
  3. ...
  4. >>> reduce(add, [1, 3, 5, 7, 9])
  5. 25

getattr

顾名思义,这个函数的作用是用来获取类A中的属性值。

  1. # encoding:utf-8
  2. class A(object):
  3. c = 3
  4. def __init__(self, a, b):
  5. self.a = a
  6. self.b = b
  7. a = A(1, 2)
  8. print(getattr(a, 'a'))
  9. print(getattr(a, 'c'))
  10. -- output
  11. 1
  12. 3

迭代器

  1. class test():
  2. def __init__(self,data=1):
  3. print("====init===")
  4. self.data = data
  5. def __iter__(self):
  6. print("====iter===")
  7. return self
  8. def __next__(self):
  9. print("====next===")
  10. if self.data > 5:
  11. raise StopIteration
  12. else:
  13. self.data+=1
  14. return self.data
  15. for item in test():
  16. print(item)

断言 assert

Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。
断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况

  1. assert expression
  2. 等价于
  3. if not expression:
  4. raise AssertionError
  5. 同时,assert后可以跟参数:
  6. >>> assert 1==2, '1 不等于 2'
  7. Traceback (most recent call last):
  8. File "<stdin>", line 1, in <module>
  9. AssertionError: 1 不等于 2

python3 新特性

变量赋值时指定类型 python 3.6

变量赋值在python3.6以后,可以用 var: type = value ,本质是 var = value ,type是var期望的类型,但是类型注释只是一种提示,并非强制的,Python解释器不会去校验value的类型是否真的是type。

  1. >>> a:int="good"
  2. >>> a
  3. 'good'
  4. >>> type(a)
  5. <class 'str'>

dataclass python3.7