编程方法
面向对象 独门秘籍:类 class
面向过程 独门秘籍:过程 def
函数式编程 独门秘籍:函数 def
函数定义
1、数学函数:
x是自变量,y是因变量;自变量的函数x的取值范围叫做这个函数的定义域;x的变化会引起y的变动。
2、函数式编程:
函数是把逻辑结构化和过程化的一种编程方式。逻辑是指你写一个购物车作业,先画一个流程图,也就是在画逻辑。
函数式编程就是:先定义一个数学函数,然后按照这个数学模型用编程语言去实现它。
3、python中的函数定义方法:
def test01(x): #def是定义函数的关键字;test是函数名;括号内是可定义形参;
"the function definitions" #""里边是描述
x += 1 #泛指代码块或程序处理逻辑
return x #定义返回值
4、面向过程和函数式编程的区别之处
定义函数
def test1():
'''test1'''
print("test1")
return 0 #有返回值
定义过程
def test02():
'''test02'''
print("test02") #没有返回值
函数调用
test1() #()代表调用test1函数;括号内可以有参数 也可以没有。
x=test1()
print(x)
结果:
test1
0
过程调用
y=test02()
print(y)
结果:
test02
None
总结:面向过程和函数式编程的区别:
相同之处:都可以被调用
不通之处:过程没有返回值;函数有返回值。
python中的面向过程,系统会默认返回一个None。
函数的三个特点
为什么使用函数,没有函数的编程只是在写逻辑(功能),想脱离函数,重用逻辑,唯一的办法就是拷贝。
例1:
with open("test01","a") as f:
f.write('this is a stop')
现在有三个函数,每个函数在处理完自己的逻辑后,都需要使用上面的逻辑,那么唯一的办法就是拷贝三次逻辑;
def test1():
print("this is test1")
with open("test01", "a") as f:
f.write("stop stop")
def test02():
print("this is test02")
with open("test01", "a") as f:
f.write("stop stop")
def test3():
print("this is test3")
with open("test01", "a") as f:
f.write("stop stop")
执行:
test1()
test02()
test3()
例2:优化后的,重复利用逻辑
def logger():
with open("test01","a") as f:
f.write('this is a stop\n')
def test1():
print("this is test1")
logger()
def test02():
print("this is test02")
logger()
def test3():
print("this is test3")
logger()
执行:
test1()
test02()
test3()
例:3:打印的时候加上时间,可扩展
import time
time_format = "%Y-%m-%d %X"
time_now = time.strftime(time_format)
def logger():
with open("test01","a") as f:
f.write('\n%s this is a stop\n'%time_now)
def test1():
print("this is test1")
logger()
def test02():
print("this is test02")
logger()
def test3():
print("this is test3")
logger()
执行:
test1()
test02()
test3()
总结 函数的三个优点
1.代码重用
2.保持一致性
3.可扩展性
函数返回值
def abc1():
print("aaaaaaa:")
return 0 #return 结束逻辑;后边的代码不执行;
print("bbbbbbb:")
def abc2():
print("aaaaaaa:")
def abc3():
print("aaaaaaa:")
return 1,"hello",["a","b","c"],{"aaa":111}
x = abc1() #x接收的是abc函数的返回值0;
y = abc2()
z = abc3()
print(x) #return 结束逻辑;后边的代码不执行;
print(y)
print(z)
'''
输出:
aaaaaaa:
aaaaaaa:
aaaaaaa:
0
None
(1, 'hello', ['a', 'b', 'c'], {'aaa': 111})
'''
函数返回值总结
1.没有return返回值:返回None
2.return返回一个值:返回object (object就是你定义的返回值;python中的所有数据类型都是对象)
3.return返回多个值:返回tuple (元组形式返回)
为什么要有返回值?
因为想知道这个函数的执行结果是否成功,然后再进行下一步操作。
函数参数
1、形参和实参
形参定义:形式参数,不是实际存在,是虚拟变量。在定义函数和函数体的时候使用形参,目的是在函数调用时候接收实参;
实参定义:实际参数,调用函数时传给函数的参数,可以是常量、变量、表达式、函数、传给形参;
2、位置参数和关键字参数
位置参数和形参要一一对应;
位置参数和关键数同时存在的时候,关键参数不能写在位置参数前面;
def test01(x,y): #x和y是形参
print(x)
print(y)
test01(1,2) #1和2是实参;位置参数和形参要一一对应;
test01(x=1,y=2) #关键参数与形参顺序无关;
#位置参数和关键数同时存在的时候,关键参数不能写在位置参数前面;
3、默认参数
特点:调用函数的时候,默认参数可有可无;
用途:默认安装值(例如安装软件的时候,设置默认安装路径;默认数据库端口值)
def moren(x,y=6): #y=6 是默认参数
print(x)
print(y)
moren(5)
输出:
5
6
4、参数组
当实参不固定的时候,形参如何定义;
参数组1: 多个实参对应形参
def canshuzu(*args): # *代表接收的参数是不固定的;*args把实参变成了一个元组;
print(args)
canshuzu(1,2,3,4,5)
'''
输出:(1, 2, 3, 4, 5)
'''
参数组2:形参和参数组结合
def canshuzu2(x,*args):
print(x)
print(args)
canshuzu2(1,2,3,4,5)
'''
输出:
1
(2, 3, 4, 5)
'''
参数组3:把关键字参数转换成字典格式输出
#*args:接收n个位置参数,转换成元组的形成
#**kwargs: 把n个关键字参数转换成字典方式
def canshuzu4(**kwargs):
print(kwargs)
print(kwargs['name'])
canshuzu4(name="aaa",age=111)
输出:
{'name': 'aaa', 'age': 111}
aaa
canshuzu4(**{"name":"aaa","age":222})
输出:
{'name': 'aaa', 'age': 222}
aaa
def canshuzu5(name,age=12,*args,**kwargs):
print(name)
print(age)
print(*args)
print(kwargs)
canshuzu5("aaa",age=22,job="it",)
输出:
aaa
22
#空的元组
{'job': 'it'}
函数局部变量和全局变量
namename = "AABBCC" #全局变量
def jubu(name):
namename = "aabbcc" #局部变量
print("before change",name,namename)
name = "ABC" #这里的name是局部变量,这个函数就是这个变量的作用域;
print("after change",name)
name = "abc" #全局变量
jubu(name) #执行函数后的结果
print(name) #此处没有执行函数,直接调用变量
print(namename) #此处没有执行函数,直接调用变量
'''
输出:
before change abc aabbcc
after change ABC
abc
AABBCC
'''
总结
局部变量:在子程序中(函数)定义的变量称为局部变量。
局部变量作用域是该变量的子程序;
全局变量:在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序;
当全局变量和局部变量同名时:
当定义局部变量的子程序内,局部变量起作用;其他地方全局变量起作用。
字符串和整数 在局部变量情况下是不能修改全局变量的值;要想改变在局部变量前加global;
除了字符串和整数、元组以外高级点的类型(列表、字典、集合、类),局部变量可以改变全局变量的值;
例子:设置局部变量修改全局变量
namename = "AABBCC"
def jubu(name):
global namename #设置局部变量修改全局变量
namename = "aabbcc"
print("before change",name,namename)
name = "ABC" #这里的name是局部变量,这个函数就是这个变量的作用域;
print("after change",name)
name = "abc"
jubu(name)
print(name)
print(namename)
输出:
before change abc aabbcc
after change ABC
abc
aabbcc
函数-递归
定义:
在函数内部,可以调用其他函数。如果一个函数在内部调用自己本身,这个函数就是递归函数。
递归特性:
1.必须有一个明确的结束条件;
2.每次进入更深一层递归时,问题规模相比上次递归都应有所减少;
3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。)
4.最大的递归层次是999层,超过 就报错;
简单的递归例子
def digui(n):
print(n)
return digui(n)
dict(0) #0是为了查看递归的次数,递归的次数最大为997次;然后就报错了
简单的递归例子2
def digui2(n):
print(n)
if int(n/2) >0:
return digui2(int(n/2))
print(n)
digui2(10)
输出:
10
5
2
1
1
高阶函数
定义
变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这就叫做高阶函数。
例如:
def add(x,y,z):
return z(x) + z(y)
result = add(3.3,-6,abs) #abs() 查看绝对值,是一个内置函数。
print(result)
输出:
9.3
扩展:
装饰器:http://blog.51cto.com/506554897/1963710
生成器:http://blog.51cto.com/506554897/1963775
迭代器:http://blog.51cto.com/506554897/1963780
本文转自506554897 51CTO博客,原文链接:http://blog.51cto.com/506554897/2070296,如需转载请自行联系原作者