函数调用图解:
1、对象的复制:copy与deepcopy
#copytest.py
#coding:utf-8
import copy
print("……copy……".decode("utf-8"))
a=[1,[5]]
b=copy.copy(a)
b[0]=10
b[1][0]=50
print("a=",a)
print("b=",b)
print("……deepcopy……".decode("utf-8"))
a=[1,[5]]
b=copy.deepcopy(a)
b[0]=10
b[1][0]=50
print("a=",a)
print("b=",b)
print("test finished!")
2、函数的定义、各种参数处理
#functiontest.py
#coding:utf-8
"""
python2.7
"""
import __builtin__
"""
python3 中,__builtin__模块改名为 builtins
dir:列出模块中有哪些方法和函数
"""
#print(dir(__builtin__))
"""
函数定义和调用的过程
定义函数时对应的参数为形参(形式参数)
调用函数时传入的参数的实参(实际参数)
"""
print("……不可变参数函数调用……".decode("utf-8"))
def fn(x,y):
x=100
y=200
print("x:{},y:{}".format(x,y))
pass
a,b=10,20
fn(a,b)
print("a:{},b:{}".format(a,b))
print(" ……可变参数(引用类型)函数调用……".decode("utf-8"))
"""
如果要保证自己的数据不被函数修改,一种方式就是转成不可变类型,比如 list转成tuple(数组),另外一种方式就是复制出一个全新的对象(deepcopy)
在这个特点上python跟我们的.Net,Java一样,使用不当会引发BUG,需要注意
"""
def fn2(x,y):
x[0]=100
y[0]=200
print("x:{},y:{}".format(x,y))
pass
a,b=[10,11],[20,21]
fn2(a,b)
print("a:{},b:{}".format(a,b))
print(" ……一般函数的定义和调用……".decode("utf-8"))
"""
四种函数类型
1.无参数无返回值
2.无参数有返回值
3.有参数无返回值
4.有参数有返回值
其实,无返回值类型意思是没有显式返回值,会默认返回一个值:None
"""
def my_add(x,y,z):
print("x={},y={},z={}".format(x,y,z))
return x+y+z
pass
a=123
b=345
"""
位置参数,调用时,从左到右实参依次对应各个形参
"""
sum=my_add(a,b,0)
print("my_add({},{},{})={}".format(a,b,0,sum))
"""
关键字参数,调用时,指定参数名,可以不按函数定义的参数顺序传值
"""
a=12
b=24
sum=my_add(y=b,x=a,z=0)
print("my_add({},{},{})={}".format(a,b,0,sum))
"""
关键字参数和位置参数可以混用,但位置参数要在前
"""
a=10
b=20
sum=my_add(a,z=0,y=b)
print("my_add({},{},{})={}".format(a,b,0,sum))
print(" ……默认参数……".decode("utf-8"))
"""
默认参数的个数不限,但必须在没有默认值的参数之后
"""
def my_add2(x,y,z=0):
print("x={},y={},z={}".format(x,y,z))
return x+y+z
pass
a=20
b=50
sum=my_add2(a,b)
print("my_add2({},{})={}".format(a,b,sum))
a=20
b=50
c=30
sum=my_add2(a,b,c)
print("my_add2({},{},{})={}".format(a,b,c,sum))
print(" ……可变参数……".decode("utf-8"))
"""
可变参数,就是不定长非关键字参数
"""
def my_add3(x, y, *args):
print("args={}".format(args))
#print("keywords={}".format(keywords))
s=0
for a in args:
s=s+a
pass
return s+x+y
pass
a=11
b=21
c=31
d=41
sum=my_add3(a,b,c,d)
print("my_add3({},{},{},{})={}".format(a,b,c,d,sum))
print(" ……接收可变关键字参数……".decode("utf-8"))
"""
不定长关键字参数,如果需要,必须为最后一个参数
"""
def my_add4(x, y, **keywords):
print("keywords={}".format(keywords))
return x+y
pass
a=12
b=22
sum=my_add4(a,b,title='test',description='my keywords test')
print("my_add4({},{},keywords)={}".format(a,b,sum))
print(" ……参数解包……".decode("utf-8"))
def my_print(x, y, z):
"""
x,y,z参数都不能为空
x:int
y:int
z:int
return x+y+z
"""
print("x={},y={},z={}".format(x,y,z))
pass
a=[3,4,5]#a=(3,4,5)
my_print(*a)#数组、列表解包为位置参数
d={"y":10,"x":20,"z":30}
my_print(**d)#字典解包为关键字参数
print(" ……函数文档……".decode("utf-8"))
"""
函数文档是给调用者看的,不会影响代码的执行
"""
print("abs(-100)={}".format(abs(-100)))
print(help(abs))
print(" ……回调函数……".decode("utf-8"))
"""
回调函数,其实就是把函数当成参数传递和执行
可以降低耦合
"""
def do_callback1():
print("this is callback function1")
pass
def do_callback2():
print("this is callback function2")
pass
def do_something(callback):
print("do something")
if callback != None:
callback()
pass
pass
do_something(do_callback1)
do_something(do_callback2)
do_something(None)
#do_something(lambda : print('my callback')) #lambda函数,3.X支持,2.X不支持
"""
lambda表示式,可以处理一些简单的功能逻辑
一般只能包含一句代码,多个语句可以用or连接,但可读性不好
"""
mymax=lambda x,y:x if x>=y else y
print("mymax(45,58)={}".format(mymax(45,58)))
"""
几个常用函数的使用
map(fn,data1,data2…) 是一个映射,第一个参数是一个函数,第二个参数是序列数据(列表/元组)
如:需求把列表中每一个元素都加10、两个列表对应下标数值相加
"""
print(" ……map list每个元素相同处理……".decode("utf-8"))
a=[1,4,7,9,11]
#b=[]
#for t in a:
# b.append(t+10)
#print("b={}".format(b))
b=map(lambda x:x+10,a)
print("b={}".format(b))
print(" ……map 两个list对应相加……".decode("utf-8"))
a=[1,4,7,9,11]
b=[21,34,27,39,41]
c=map(lambda x,y:x+y,a,b)
print("c={}".format(c))
"""
reduce(fn,data),用于做累计运算,fn有两个参数,返回值为两个元素之间运算结果
需求:列表中所有元素相乘
"""
from functools import reduce
print(" ……reduce 列表中所有元素相乘……".decode("utf-8"))
a=[2,4,6,8,10]
#ret=1
#for t in a:
# ret *=t
#print("ret={}".format(ret))
ret=reduce(lambda x,y:x*y,a)
print("ret={}".format(ret))
"""
filter(fn,data),用来过滤数据,fn接受一个参数,返回一个判断结果布尔值
需求:找出所有大于80的数据
"""
print(" ……filter 找出所有大于80的数据……".decode("utf-8"))
a=[10,90,30,112,20,300]
#b=[]
#for t in a:
# if t > 80:
# b.append(t)
# pass
# pass
#print("b={}".format(b))
b=filter(lambda x:x>80,a)
print("b={}".format(b))
'''
闭包,在函数A中定义函数B,调用A返回函数B,在函数B中访问函数A中的变量,函数A中的变量在外部不能被修改
需求:提供一个函数获取自动增长的ID
'''
print(" ……闭包 提供一个函数获取自动增长的ID……".decode("utf-8"))
#num=0
#def get_id():
# global num
# num += 1
# return num
#print(get_id())
#print(get_id())
#num=0
#print(get_id())
#print(get_id())
#python3实现
#def get_id():
# num = 0
# def get_id():
# nonlocal num
# num+=1
# return num
# return get_id
#python2实现
def get_id():
d = {'y' : 0}
def get_inner_id():
d['y'] += 1
return d['y']
return get_inner_id
callback = get_id()
print(callback())
print(callback())
print(callback())