python的函数参数传递都是引用,所以在函数内部会改变原来的参数值。
def desc_pet(names):names[0] = "what?"names = ["dog", "cat", "eagle"]desc_pet(names)print(names)--['what?', 'cat', 'eagle']
函数参数:5种
必选参数和默认参数就不用多说了,主要介绍可变参数和关键字参数以及命名关键字参数。
def desc_pet(animal_type, animal_name):print("\n I have a " + animal_type + ".")print("it's name is " + animal_name + ".")desc_pet("dog", "wangwang")desc_pet(animal_name="miaomiao", animal_type="cat")--I have a dog.it's name is wangwang.I have a cat.it's name is miaomiao.
可变参数
###### *作为形参 ####### *numbers中的星号让python创建一个名为nubmers的空元组,# 并将收到的所有值都封装到这个元组中def calc(*numbers):"""caculate number"""print("numbers:", numbers)sum = 0for n in numbers:sum = sum + n * nreturn sum>>> calc()numbers: ()0>>> calc(1,2)numbers: (1, 2)5# 同样,我们可以传一个list或tuple>>> nums=[1,2,3]>>> calc(*nums)numbers: (1, 2, 3)14>>> calc(nums)numbers: ([1, 2, 3],)Traceback (most recent call last):File "<stdin>", line 1, in <module>File "<stdin>", line 6, in calcTypeError: can't multiply sequence by non-int of type 'list'# 也可以与其他参数混用>>> def test(a, b, *arg):... print(a,b, arg)...>>> test(1, 2, 3, 4)(1, 2, (3, 4))>>> test(1, 2, 3)(1, 2, (3,))###### *作为实参 ######>>> def f(a, b, c):... print(a, b, c)...>>> f(1, 2, 3)1 2 3>>> l = [1, 2, 3]>>> f(*l)1 2 3# 再看几种情况# 1. l是list时,*l是错误语法>>> *lFile "<stdin>", line 1SyntaxError: can't use starred expression here# 2. 这样是直接传递一个参数,该参数是一个list>>> f(l)Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: f() missing 2 required positional arguments: 'b' and 'c'# 3. 参数传多了>>> f(*[1,2,3,4])Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: f() takes 3 positional arguments but 4 were given
关键字参数
# **kw中的星号让python创建一个名为kw的空字典,# 并将收到的所有key-value对都封装到这个字典中。def person(name, age, **kw):print('name:', name, 'age:', age, 'other:', kw)>>> person('Michael', 30)name: Michael age: 30 other: {}>>> person('Adam', 45, gender='M', job='Engineer')name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}>>> extra = {'city': 'Beijing', 'job': 'Engineer'}>>> person('Jack', 24, **extra)name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}###### ** 作为实参 ######>>> def f(a, b, c):... print(a, b, c)...>>> d={'b':2, 'c':3}>>> f(1, **d)1 2 3>>> e = {'b':2, 'd':4}>>> f(1, e)Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: f() missing 1 required positional argument: 'c'
命名关键字参数
# 只接收city 和 job 作为关键字参数def person(name, age, *, city, job):print(name, age, city, job)>>> person('Jack', 24, city='Beijing', job='Engineer')Jack 24 Beijing Engineer>>> person(age=24, name='Jack', city='Beijing', job='Engineer')Jack 24 Beijing Engineer>>> person('Jack', 24, 'Beijing', 'Engineer')Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: person() takes 2 positional arguments but 4 were given# 第二种方式,可变参数后的参数,默认为命名关键字参数def person(name, age, *args, city, job):print(name, age, args, city, job)>>> person('Jack', 24, 'Beijing', 'Engineer')Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: person() takes 2 positional arguments but 4 were given
回调函数
例如A是一个函数,他自身作为一个参数,传递给B,在B里被调用,那么A就叫做回调函数,B叫做中间函数。
简单示例如下:
# 回调函数1def f1(x):return x+2# 回调函数2def f2(x):return x+1# 中间函数,接受一个函数作为参数def addANumber(f, x):return 1 + f(x)# main成为起始函数,也就是调用中间函数的函数def main():i = addANumber(f1, 1)i = addANumber(f2, 1)if __name__ == "__main__":main()
内置函数
map
map需要两个参数,一个函数,一个列表,map会把函数依次作用在列表上,并返回一个列表。
>>> def f(x):... return x * x...>>> map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])[1, 4, 9, 16, 25, 36, 49, 64, 81]
reduce
再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3…]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
>>> def add(x, y):... return x + y...>>> reduce(add, [1, 3, 5, 7, 9])25
getattr
顾名思义,这个函数的作用是用来获取类A中的属性值。
# encoding:utf-8class A(object):c = 3def __init__(self, a, b):self.a = aself.b = ba = A(1, 2)print(getattr(a, 'a'))print(getattr(a, 'c'))-- output13
迭代器
class test():def __init__(self,data=1):print("====init===")self.data = datadef __iter__(self):print("====iter===")return selfdef __next__(self):print("====next===")if self.data > 5:raise StopIterationelse:self.data+=1return self.datafor item in test():print(item)
断言 assert
Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。
断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况
assert expression等价于if not expression:raise AssertionError同时,assert后可以跟参数:>>> assert 1==2, '1 不等于 2'Traceback (most recent call last):File "<stdin>", line 1, in <module>AssertionError: 1 不等于 2
python3 新特性
变量赋值时指定类型 python 3.6
变量赋值在python3.6以后,可以用 var: type = value ,本质是 var = value ,type是var期望的类型,但是类型注释只是一种提示,并非强制的,Python解释器不会去校验value的类型是否真的是type。
>>> a:int="good">>> a'good'>>> type(a)<class 'str'>
