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 = 0
for n in numbers:
sum = sum + n * n
return 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 calc
TypeError: 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是错误语法
>>> *l
File "<stdin>", line 1
SyntaxError: 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叫做中间函数。
简单示例如下:
# 回调函数1
def f1(x):
return x+2
# 回调函数2
def 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-8
class A(object):
c = 3
def __init__(self, a, b):
self.a = a
self.b = b
a = A(1, 2)
print(getattr(a, 'a'))
print(getattr(a, 'c'))
-- output
1
3
迭代器
class test():
def __init__(self,data=1):
print("====init===")
self.data = data
def __iter__(self):
print("====iter===")
return self
def __next__(self):
print("====next===")
if self.data > 5:
raise StopIteration
else:
self.data+=1
return self.data
for 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'>