python函数与函数式编程

使用函数的优点:1,代码重用   2.保持一致性     3,可扩展性, 是一种面封装

# 面向对象编程》类》class     面向对象:就是把什么东西都看成是对象处理
# 面向过程》过程》过程是没有返回值的函数,把逻辑功能包含到def定义的过程当中,用的时候直接使用函数名加小括号调用它
# 函数式编程》函数》def#函数是逻辑结构化和过程化的一种编程方法

def fun1():#定义一个函数
    '''testing'''
    print('in the fun1')
    return 0#如果执行了return这个函数下面的代码不会在执行

def fun2():#定义一个过程
    '''testing2'''
    print('in the fun2')

x=fun1()#x接收了fun1的返回值
y=fun2()
print('from fun1 return is %s'%x)
print('from fun2 return is %s'%y)#python中给过程定义了返回值none

import time
def logger():
    time_format='%y-%m-%d %X'#定义时间年月日大写(X)定义小时分钟秒
    time_current=time.strftime(time_format)#引用上面时间格式最后按上面的显示时间
    with open('a.txt','a+') as f:
        f.write('%s end action
'%time_current)

def test1():
    print('in the test1')
    logger()

def test2():
    print('in the test2')
    logger()

def test3():
    print('in the test3')
    logger()
test1()
test2()
test3()
函数返回值
def test1():
    print('in the test1')
    return 0#定义返回值,返回结束,不会再执行后面语句,可以返回(True,False,[11,22]等)
test1()
x=test1()#函数return后面是什么值,x就等于什么值,把0赋予了x
print(x)

def test2():
    print('in the test1')#没有return返回值,默认返回none
    return test4 # 这样定义可以返回test4内存地址

def test3():
    print('in the test1')
    return 0#返回值=1返回对象

def test4():
    print('in the test1')
    return 1,'hello',['alex'],{'alex':'30'}#返回值>1可以返回任意类型,返回值以元祖显示
#函数返回值的作用是为了后面其它程序的逻辑需要根据这个返回值的结果进行操作
a=test2()
b=test3()
c=test4()
print(a)
print(b)
print(c)

def add(a, b):
    sum = a + b
    return sum
print(add(6, 7))# 在这里调用add函数,求2个数的和,并输出调用后的结果
形参,实参
def test(x,y):#x,y就是形参(形象的存在,是虚拟变量)
    print(x)
    print(y)
#形参和实参是从左到右一一对应的
test(1,2)#位置参数调用,1,2就是实参,(实际存在的,占用空间的)把1定义给了x,把2定义给了y,数据传送单向,实参传给形参,不能形参传给实参,调用函数时传给函数的参数
test(y=2,x=1)#关键字调用,与形参顺序无关
test(3,y=2)#既有位置调用也有关键字调用,关键参数不能写在位置参数前面

默认参数
def test(x,y=2):#默认参数:调用函数的时候默认参数可有可无,非必传,用途:1.默认安装值,2.数据库端口值,3.默认参数y=2必须放在后面,可以有多个默认参数
    print(x)
    print(y)
test(1) #实际会打印1,2
参数组
def test(*args):#1.参数组(传递不固定数参数,动态),接收N个位置参数,转换成tuple方式,
以*开头定义变量名,可以接收多个实参将值放到'args'变量中,打印出元祖
    print(args)

test(1,2,3,4,5,6,6)
test(*[1,2,3,4,5,6,6])#  args=tuple([1,2,3,4,5,6,6])

def test1(x,*args):#位置参数与参数组结合使用
    print(x)
    print(args)
test1(10,2,3,4,5,6,7)#打印两行

def f1(*args):
    print(args,type(args))
li=[11,22,33]
f1(li)#当做元祖中的一个元素输出
f1(*li)#把列表的元素元祖的原色输出

def f1(**kwargs):
    print(kwargs,type(kwargs))
dic={'k1':123}
f1(**dic)#把字典传进去,对应两个**

def test2(**kwargs):#2.**kwargs把n个关键字参数,转换为字典的方式
    print(kwargs)
    print(kwargs['name'])#可以取到字典的值
    print(kwargs['age'])
test2(name='alex',age=8)#name=字典key,alex=字典values
test2(**{'name':'alex','age':8})#(**{'name':'alex','age':8})=dict(name='alex',age=8)


def test3(name,**kwargs):
    print(name)
    print(kwargs)
test3('alex',age=8,sex='')#参数组跟位置参数结合使用

def test4(name,age=8,**kwargs):#参数组与位置参数默认参数结合使用,参数组放最后面
    print(name)
    print(kwargs)
    print(age)
test4('alex',age=8,sex='',hobby='美女')#age=8也可直接写成8或不写


def test5(name,age=18,*args,**kwargs):#位置参数,默认参数,*args,**kwargs参数组,组合使用(*args在前,**kwargs在后),可称为万能参数
    print(name)
    print(age)
    print(kwargs)
    print(args)
test5('alex',age=8,sex='',hobby='美女')#打印alex,8,{'sex': '男', 'hobby': '美女'},()
函数里面引用其他函数
def test5(name,age=18,*args,**kwargs):
    print(name)
    print(age)
    print(kwargs)
    print(args)
    logger('TEST5')#一个函数里面引用其他函数

def logger(source):
    print('from %s'% source)#谁调用它给它传一个参数,自己是谁。
test5('alex',age=8,sex='',hobby='美女')

函数式编程与函数不同

函数式编程语言

输入是确定的输出就是确定的

局部变量,全局变量,作用域
在子程序中定义的变量为局部变量,在程序一开始定义的变量为全局变量,
全局变量作用域是整个程序,局部变量作用域是定义改变量的子程序,只在小函数里面有效
当全局变量与局部变量同名时
在定义局部变量的子程序内,局部变量起作用,在其他地方全局变量起作用
全局变量可以已定义为:大写
局部变量可以定义为:小写

school='oldboy'#全局变量,
def change_name(name):
    global school#把局部变量改为全局变量,函数里面默认局部变量是无法更改全局变量的,如果要改需要用global声明,一般不建议改,如果函数多次调用一但改了会造成逻辑混乱。字符串,整数需要加global,列表,集合,字典,类,都是可以将局部变量改为全局变量的(不需要加任何声明)
    school='oldboy1'
    print('before change',name,school)#改之前名字
    name='ALEX'#局部变量,这个函数就是这个变量的作用域,就是说这个函数只在这个变量里生效
    print('after change',name)
print('school:',school)#这里打印的是调用前最外层的全局变量
name='alex'
change_name(name)#把name传给了函数,传之前是alex
print(name)
print('school:',school)#这里打印的是调用后的局部变量更改为全局变量的内容


def change_name():#这种写法虽然也可以,但是一定不能这样写,如果非要写必须在外面声明全局变量
    global name
    name='alex'
change_name()
print(name)


names=['zc','zc2','zc3']
def change_name():
    names[0]='ZC'#列表,集合,字典,类,都是可以将局部变量改为全局变量的,不需要声明
   print('inside func'names)
change_name()
print(names)

person='zc'
def fun1():
    a=123
    global person
    person='cz'
    print(person)
    print(a)
def fun2():
    a=234
    print(a)
    print(person)
fun1()
fun2()
 
作业:
写函数,计算传入字符串中【数字】、【字母】、【空格] 以及 【其他】的个数:
def func1(s):
    alpha_num =0
    spance_num=0
    digit_num=0
    others_num=0
    for i in s:
        if i.isdigit():
            digit_num+=1
        elif i.isspace():
            spance_num+=1
        elif i.isalpha():
            alpha_num+=1
        else:
            others_num+=1
    return ({'alpha':alpha_num},spance_num,digit_num,others_num)
a=func1('fa2 dsffecgf?')
print(a)
写函数,判断用户传入的对象(字符串、列表、元组)长度是否大于5:
def fun(arg):
    if isinstance(arg,str)or isinstance(arg,list)or isinstance(arg,tuple):
        if len(arg)>5:#len不能判断数字,isinstance:是用来判断一个对象的变量类型
            return True
        else:
            return False
    return None
# temp='233fdsf'
# temp=[12,'ws']
temp='asdsdd'
ret=fun(temp)
print(ret)
写函数,检查用户传入的对象(字符串、列表、元组)的每一个元素是否含有空内容:
def has_space(args):
    ret=True
    for i in args:
        if i.isspace():
        #if " "in i:
            ret =False
            break
    return ret
result=has_space('12323 _{:')
print(result)
写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者
def f2(args):
    if len(args)>2:
        return args[0:2]
    return args
li=[1,2,34,]
r=f2(li)
print(r)

   
写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者
def f4(args):
    ret=[]
    for i in range(len(args)):
        if i %2==1:
            ret.append(args[i])
        else:
            pass
    return ret
li=[1,2,3,4,5]
r=f4(li)
print(li)
print(r)
写函数检查传入字典的每一个value的长度,如果大于2那么仅保留前两个长度的内容并将新内容返回给调用者
  
写函数,利用递归获取斐波那契数列中的第 10 个数,并将该值返回给调用者

 

原文地址:https://www.cnblogs.com/zcok168/p/9141933.html