1 函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,比如print()。但你也可以自己创建函数,这被叫做用户自定义函数。

1.1过程与函数

1.面向对象 : 类(class)

2.面向过程: 过程 (def)

3函数式编程 : 函数(def)

过程与函数

#Author:Anliu

#函数

def fun1():

"""testing01"""

print("this is a testing1")

return 0

#过程

def fun2():

"""testing02"""

print("this is a testing2")

x = fun1()

y = fun2()

我们说在编程中,过程和函数都是可以调运的实体,将没有返回值的函数叫做过程。

#Author:Anliu

函数

def fun1():

"""testing01"""

print("this is a testing1")

return 0

过程

def fun2():

"""testing02"""

print("this is a testing2")

x = fun1()

y = fun2()

print("from func1 return is %s"%x)

print("from func2 return is %s"%y)

执行结果:

this is a testing1

this is a testing2

from func1 return is 0

from func2 return is None

由此可见,python中默认的不再将函数个过程区分。

1.2 为什么使用函数

1.代码重用

2.保持一致性

3.可扩展

#Author:Anliu

import time

def logger():

,,,xxxxxxxxxx,,,

time_format = '%Y-%m-%d %X'

time_current = time.strftime(time_format)

with open("a.txt","a",encoding=("utf-8")) as f:

f.write("%s end action\n"%time_current)

def test1():

'''testing'''

print("in the test1")

logger()

def test2():

'''testing'''

print("in the test2")

logger()

def test3():

print("in the test3")

logger()

test1()

test2()

test3()

上述代码实现了,在不同函数执行时打印日志的功能,一次说明函数实现的 “一致性,以及可扩展性”

1.2定义一个函数

你可以定义一个由自己想要功能的函数,以下是简单的规则:函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。

任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。

函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。

函数内容以冒号起始,并且缩进。

return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。

1.3 语法

Python 定义函数使用 def 关键字,一般格式如下:

def 函数名(参数列表):

函数体

默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。

#Author:Anliu

def hello():

print("hello world")

hello()

#Author:Anliu

def area(width,heigt):

return width * heigt

def print_welcome(name):

print("Wlcome",name)

print_welcome("anliu")

w = 4

h = 5

print("width=",w,"heigt=",h,"area=",area(w,h))

1.4 函数返回值

1.4.1 返回值的作用

后续程序需要函数值的确认。

1.4.1 返回值的效果

return执行的效果是:返回一个值,且终止当前程序运行。

#Author:Anliu

def test1():

print("in the test1")

return 0

print("test end")

x = test1()

print(x)

执行结果:

in the test1

1.4.2 返回值的类型

#Author:Anliu

def test1():

print("in the test1")

def test2():

print("in the test2")

return 0

def test3():

print("in the test2")

return 1,"hello",["dajiang","dajiangliu","xxxx"],{"jingling:shibachai"}

def test4():

print("in the test3")

return test1

x = test1()

y = test2()

z = test3()

w = test4()

print(x)

print(y)

print(z)

print(w)

执行结果:

in the test1

in the test2

in the test3

in the test3

None

0

(1, 'hello', ['dajiang', 'dajiangliu', 'xxxx'], {'jingling:shibachai'})

当没有返回值时,返回NUll。

当返回值时一个特定值时,返回这个值。

当返回值是多个值时,返回的是一个元组。

当返回值是一个函数名时,返回的是函数的内存地址。

当返回值时一个函数时,返回值时函数的执行结果。

1.5 函数调运

1.5.1 参数类型

位置参数

关键字参数

默认参数

参数组

#Author:Anliu

def test(x,y): #形参

print(x)

print(y)

test("x","y") #位置实参调运,形参和实参是一一对应

test(y=2,x=3) #关键字参数调运,与形参位置无关。

test(x=2,3) #关键参数不能写在位置参数之前。

test(3,y=2) #位置参数和关键字参数同时存在,以位置参数调运为主。

(1)位置实参调运,形参和实参是一一对应

(2)关键字参数调运,与形参位置无关。

(3)关键字参数不能写在位置参数之前。

(4)位置参数和关键字参数同时存在,以位置参数调运为主。

#Author:Anliu

def test(x,y=2):

print(x)

print(y)

test(1,3)

默认参数的特点:调运函数的时候,默认参数非必须传递

用途:参数在不修改其值的情况下,使用默认值

#Author:Anliu

def test (x,y,z=2):

print(x)

print(y)

print(z)

test(1,3)

实参不能大于形参数目。

实际 上,生产环境中,实参是需要存在多个,如何去定义实参呢?局需要参数组的概念。

#Author:Anliu

def test(*args):

print(args)

test(1,3,4,5,6,7,8,9,)

test([1,2,2,4,5,7,])

执行结果:

(1, 3, 4, 5, 6, 7, 8, 9)

(1, 2, 2, 4, 5, 7)

执行结果是元组。

#Author:Anliu

def test(x,y,args):

print(x)

print(y)

print(args)

test(1,3,4,5,6,7,8,9,)

test(*[1,2,2,4,5,7,])

参数组和形式参数可以混合使用。

#Author:Anliu

def test(**kwargs):

print(kwargs)

test(name='anliu',age=8,sex='F')

test(**{'name':"anliu","age":18})

把N个关键字参数,转换为字典的形式

执行结果:

{'name': 'anliu', 'age': 8, 'sex': 'F'}

{'name': 'anliu', 'age': 18}

可将关键字或者字典传递,并得到一个字典的输出结果。

参数和参数组同时使用也是没有问题的。

#Author:Anliu

def test(name,age=8,**kwargs):

print(name)

print(age)

print(kwargs)

test("anliu",age=28,hobby='paoniu',sex='F')

执行结果:

anliu

28

{'hobby': 'paoniu', 'sex': 'F'}

*args : 接受N个位置参数,转化成元组的形式

**kwargs :接受N个关键字参数,转化成字典的形式

1.6 变量

1.6.1 局部变量

#Author:Anliu

def change_name(name):

print("before change",name)

name = "Auliu" #局部变量,这个函数就是变量的作用域

print("after change",name)

name = "anliu"

change_name(name)

print(name)

局部变量,这个函数就是变量的作用域

1.6.2 全局变量

在函数内是不能修改全局变量的值

#Author:Anliu

school = "xiyunkeji" #全局变量

def change_name(name):

school = "baiyijishu" #在函数内是不能修改全局变量的值

print("before change",name,school)

name = "Auliu" #局部变量,这个函数就是变量的作用域

print("after change",name)

name = "anliu"

change_name(name)

print(name,school)

输出结果:

before change anliu baiyijishu

after change Auliu

anliu xiyunkeji

定义global之后,全局变量也是可以在函数内修改的。

#Author:Anliu

school = "xiyunkeji" #全局变量

def change_name(name):

global school #定义global之后,全局变量也是可以在函数内修改的。

school = "baiyijishu" #在函数内是不能修改全局变量的值

print("before change",name,school)

name = "Auliu" #局部变量,这个函数就是变量的作用域

print("after change",name)

name = "anliu"

change_name(name)

print(name,school)

输出结果:

before change anliu baiyijishu

after change Auliu

anliu baiyijishu

看一下代码:

#Author:Anliu

names = ["anliu","anttech","xingyun"]

def change_name():

names[0] = "Anliu"

print(names)

change_name()

print(names)

执行结果:

['Anliu', 'anttech', 'xingyun']

['Anliu', 'anttech', 'xingyun']

需要说明的是,当全局变量为列表,字典,集合包括类,这种复杂的数据类型及数据结果,函数中也是可以修改全局变量的。

1.6.3变量内存的回收机制

python解释器当变量名不存在时,变量内存会被回收。

1.7 递归函数

在函数内部,可以调运其他函数。如果一个函数在内部调运自身,这个函数就是递归函数。

递归的特性:

1.必须要有一个明确的结束条件。

2.每次进入更深的一层递归时,问题规模相比上次都应有所减少。

3.递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调运是通过栈(stack)这种数据结构实现的,每当进入一个函数调运,栈就会加一层栈帧。每当函数返回,栈就会减少一层栈帧。由于栈的大小不是无限的,所以,递归调运的次数过多,会导致栈溢出)

#Author:Anliu

def calc(n):

print(n)

if int(n/2) > 0:

return calc(int(n/2))

print("-->",n)

calc(10)

1.8 高阶函数

变量可以指向函数,函数的参数支持能接受变量,那么一个函数就可以接受另一个函数作为参数,这种函数就称之为高阶函数。

#Author:Anliu

def add(a,b,f):

return f(a) + f(b)

x = add(1,-6,abs)

print(x)

以上abs是求绝对值的函数。

1.9 匿名函数

#Author:Anliu

calc = lambda x:x*3

print(calc(2))

没有函数名

1.10 高阶函数

(1)把一个函数名当做实参传递给另一个函数

(2)返回值中包含函数名

#Author:Anliu

def test1(func):

print(func)

def bar():

print("in the bar")

test1(bar)

func = bar

func()

import time

def bar():

time.sleep(3)

print("in the bar")

def test2(func):

print(func)

return func

t = test2(bar)

print(t)

t()

1.11 嵌套函数

在一个函数体内定义另一个函数。

#Author:Anliu

def foo():

print("in the foo")

def bar():

print("in the bar")

bar()

foo()

2 函数式编程介绍

函数是python内建支持的一种封装,我们通过把大段代码折成函数,通过一层一层的函数调运,就可以把复杂的任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程设计的基本单元。

而函数式编程,虽然可以归结到面向过程的的程序设计,但是其思想更接近科学计算。

这使得我们要明确计算机和计算的概念。

在计算机层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断,和跳转指令,所以汇编语言是最贴近计算机的语言。

而计算则指的是数学意义上的计算,越是抽象的计算,里计算机硬件越远。

对应到编程语言,就是越低级的语言,越贴近计算机,执行效率高,比如C语言;级别越高的语言,越贴近计算,抽象程度高,执行效率低,比如lisp语言。

函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入确定,输出就是确定的,这种纯函数我们称之为没有副作用。而容许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可以得到不同的输出,因此这种函数是有副作用的。

python对函数式编程提供部分支持。由于python容许使用变量,因此python不是纯函数式编程式语言。

3 装饰器

定义:装饰器:装饰器本质是函数,(函数是有特定的功能),装饰器的功能就是装饰其他函数,就是为其他函数添加附加功能。

原则:1.不能修改被装饰函数的源代码。

2.不能修改被装饰的函数的调运方式。

(装饰器对被装饰函数来说是透明的)

实现装饰器知识储备

1.函数即“变量”

2.高阶函数

(1)把一个函数名当做实参传递给另一个函数。

(2)返回值中包含函数名。

3嵌套函数

装饰器=高阶函数+嵌套函数

看以下装饰器示例:

#Author:Anliu

import time

def timmer(func):

def warpper(*args,**kwargs):

start_time=time.time()

func()

stop_time=time.time()

print("the func run time is %s"%(stop_time-start_time))

return warpper

@timmer

def test1():

time.sleep(3)

print("in the test1")

test1()

为什么我们需要装饰器?

比如我们有两个函数,现在需要给这两个函数添加打印日志的功能:

#Author:Anliu

def test1():

pass

def test2():

pass

test1()

test2()

我们改如何去做?

方法一:

#Author:Anliu

import time

def test1():

print("this is a test1")

format_time = "%Y-%m-%d %X"

time_current = time.strftime(format_time)

print(time_current)

def test2():

print("this is a test2")

format_time = "%Y-%m-%d %X"

time_current = time.strftime(format_time)

print(time_current)

test1()

test2()

方法二:

#Author:Anliu

import timedef

logger():

'''xxxxx'''

format_time = "%Y-%m-%d %X"

time_current = time.strftime(format_time)

print(time_current)

def test1():

'''xxxxx'''

print("this is a test1")

logger()

def test2():

'''xxxxx'''

print("this is a test2")

logger()

test1()

test2()

此法看似可行。但是问题来了,如果实在给程序已经应用到了生产环境,test函数已经承载业务,此时代码时不容许改变的,修改源代码,是有风险存在的。该当如何是好?

利用高阶函数实现对test1()进行装饰一个打印日志功能。

#Author:Anliu

import time

def test1():

'''xxxxx'''

print("this is a test1")

def logger(func):

'''xxxxx'''

format_time = "%Y-%m-%d %X"

time_current = time.strftime(format_time)

func()

print(time_current)

logger(test1)

这样也能实现对函数的装饰。即在不修改被装饰函数源代码的情况下为其添加功能。

但是问题来了,虽然没有修改源代码,但是修改了函数的调运方式。

再看如下代码:

#Author:Anliu

import time

def test1():

'''xxxxx'''

print("this is a test1")

def test2():

'''xxxxx'''

print("this is a test2")

def logger(func):

'''xxxxx'''

format_time = "%Y-%m-%d %X"

time_current = time.strftime(format_time)

print(time_current)

return func

test1 = logger(test1)

test1()

test2 = logger(test2)

test2()

这样,我们用高阶函数的第二个特性,返回值中包含函数名,来实现了在不修改函数调运方式的情况下,完成对函数的装饰。

这种方式看起来貌似没有问题,其实很扯淡。因为只要在我们这个实例上生效。那如果是我们的需求变了,不再是先输出实践,再执行函数,而是先执行函数,再打印时间。

就是说,上面代码执行结果是:

2019-07-13 00:31:15

this is a test1

我们现在的需求这样:

this is a test1

2019-07-13 00:31:15

#Author:Anliu

import time

def test1():

'''xxxxx'''

print("this is a test1")

def logger(func):

'''xxxxx'''

return func

format_time = "%Y-%m-%d %X"

time_current = time.strftime(format_time)

print(time_current)

test1 = logger(test1)

test1()

this is a test1

完了,这下输出结果有问题了。

我们前面说的retrun()既有返回值,同时终止程序。

该问题我们来用嵌套函数来解决:

#Author:Anliu

import time

def test1():

'''xxxxx'''

print("this is a test1")

def timer (func):

def logger():

'''xxxxx'''

func()

format_time = "%Y-%m-%d %X"

time_current = time.strftime(format_time)

print(time_current)

return logger

test1 = timer(test1)

test1()

输出结果:

this is a test1

2019-07-13 00:49:58

这个我们实现了一个装饰器功能。

再看这两行代码:

test1 = timer(test1) test1()

很麻烦,python解释题给我们提供了一个“语法糖”,我们可以使用“语法糖”来实现。

#Author:Anliu

import time

def timer (func):

def logger():

'''xxxxx'''

func()

format_time = "%Y-%m-%d %X"

time_current = time.strftime(format_time)

print(time_current)

return logger

@timer

def test1():

'''xxxxx'''

print("this is a test1")

test1()

这样就实现了一个完整的装饰器。

其实还有问题:

若函数有参数传递,该如何呢?

#Author:Anliu

import time

def timer (func):

def logger():

'''xxxxx'''

func()

format_time = "%Y-%m-%d %X"

time_current = time.strftime(format_time)

print(time_current)

return logger

@timer # test1 = logger(test1)

def test1():

'''xxxxx'''

print("this is a test1")

test1()

@timer

def test2():

'''xxxxx'''

print("this is a test1")

test2()

@timer

def test3(name):

'''XXXXX'''

print("test3",name)

test3("anliu")

当有参数存在时,又开始报错。

这是因为,本质上语法糖是@timer 等同于 test1 = logger(test1),起作用是将test1传递给logger函数。我们只需要将logger函数的形参,以及函数内的函数调运实参修改即可:

#Author:Anliu

import time

def timer (func):

def logger(args,**kwargs):

'''xxxxx'''

func(args,**kwargs)

format_time = "%Y-%m-%d %X"

time_current = time.strftime(format_time)

print(time_current)

return logger

@timer # test1 = logger(test1)

def test1():

'''xxxxx'''

print("this is a test1")

test1()

@timer

def test2():

'''xxxxx'''

print("this is a test1")

test2()

@timer

def test3(name,age,aaa):

'''XXXXXXXXX'''

print("test3",name,age,aaa)

test3("anliu","age","aaa")

python采用函数式编程模式吗_Python函数与函数式编程相关推荐

  1. python采用函数式_python -- 函数以及函数式编程

    函数以及函数式编程 到目前为止,我们的Python 代码已经实现了小的分块.它们都适合处理微小任务, 但是我们想复用这些代码,所以需要把大型代码织成可管理的代码段.代码复用的第一步是 使用函数,它是命 ...

  2. 过程或函数的副作用是_Python函数和函数式编程(两万字长文警告!一文彻底搞定函数,建议收藏!)...

    Python函数和函数式编程 函数是可重用的程序代码段,在Python中有常用的内置函数,例如len().sum()等. 在Pyhon模块和程序中也可以自定义函数.使用函数可以提高编程效率. 1.函数 ...

  3. 在python子程序中、使用关键字_python函数(四)

    一.函数是什么? 函数一词来源于数学,但编程中的「函数」概念,与数学中的函数是有很大不同的,编程中的函数在英文中也有很多不同的叫法.在BASIC中叫做subroutine(子过程或子程序),在Pasc ...

  4. python 函数式编程包_python 函数支持函数式编程的包operator partial

    itemgetter和attrgetter能替代从序列中取出元素或读取对象属性的lambda表达式,会自动构建函数 itemgetter 1,根据元组某个字段给元组列表排序,下例中 itemgette ...

  5. python快乐编程百度云_Python趣码快乐编程

    Python的安装/2 n 下载安装相应版本的Python安装包/2 n 验证Python是否安装成功/4 n 编辑器PyCharm的安装和使用/5 n PyCharm的下载与安装/5 n PyCha ...

  6. python调用c++类内静态函数_Python与C++混合编程 - 2.4 - 使用局部静态对象

    项目地址: https://github.com/tushushu/EssentialCython​github.com 参考书籍: <Essential C++ 中文版> 编程环境: M ...

  7. python编程头文件_python头文件的编程风格

    python头文件的编程风格 发布时间:2020-09-03 10:23:25 来源:亿速云 阅读:96 作者:小新 小编给大家分享一下python头文件的编程风格,希望大家阅读完这篇文章后大所收获, ...

  8. python不定长参数怎么相加_python函数不定长参数使用方法解析

    这篇文章主要介绍了python函数不定长参数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 pathon中的函数可以使用不定长参数,可以 ...

  9. python 值传递还是引用传递_python函数是值传递还是引用传递

    在网上看python的基础知识,看到函数这一章的时候,看到这么一段话: 所有参数(自变量)在Python里都是按引用传递.如果你在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了. ...

最新文章

  1. leetcode112 路径总和
  2. Linux 高可用(HA)集群之keepalived
  3. 算法日记-01-算法和数据结构概览
  4. 逆透视变换详解 及 代码实现(二)
  5. 面试题,如何让你从0-1的做一款产品出来,你会怎么做?
  6. 苹果AirPods大受欢迎:与iPod鼎盛时期相当
  7. 【Java从0到架构师】Spring - 注解
  8. 【CVPR 2020】Learning RoI Transformer for Oriented Object Detection in Aerial Images
  9. easyUI跨Tab操作datagrid
  10. 电子工业出版社PPT图书优秀作者上海书城讲座
  11. 如何使用计算机中的导出,解决方案:如何使用Canon 2525i复印机将文档扫描到计算机中并生成PDF格式?...
  12. rpc调用过程原理分析以及Dubbo、Feign调用过程
  13. 今日头条阅读量怎么刷_今日头条提升头条号阅读量的几大方法
  14. 【前端面试必读】w3c标准是什么?
  15. SAP UI5 应用开发教程之一百零四 - SAP UI5 表格控件的支持复选(Multi-Select)以及如何用代码一次选中多个表格行项目
  16. 赛门铁克2010年大中国区杰出用户奖获奖名单
  17. VMware上使用Ubuntu的问题集合
  18. Docker(安装常用命令)
  19. 图书系统(轻松上手)
  20. SoundPool播放.mp3音频

热门文章

  1. ilm 和dlm差异_电力通信系统--加密芯片.pdf
  2. 程序员在很多人心里的作用...
  3. Spring Cloud Feign如何实现JWT令牌中继以传递认证信息
  4. Java + Vue 实现的在线考试系统
  5. IDEA不愧为神器,结合Groovy脚本,简直无敌!
  6. DevOps也要考虑安全问题:微软、任天堂等知名公司源码遭泄露
  7. IntelliJ IDEA 2019.2最新解读:性能更好,体验更优,细节处理更完美!
  8. UML之类图和包图,对象图
  9. qthread destroyed while thread is still running
  10. 海康摄像头取、录像机RTSP视频流的字串格式