无论在任何编程语言中,函数的地位都举足轻重。这一回我们学习python函数,捎带温习一下javascript的函数。
函数的部分,我准备从函数的定义、参数、模块化、高阶函数等部分进行讨论。
函数的定义
js的函数:
// js的函数定义
// 1. 定义式
// 函数关键字 + 驼峰命名 + () + {}
function getInfo () {}
// 2. 变量式
const getInfo = function () {}
// 或者箭头函数形式
const getInfo = () => {}
// 3. 构造器 当然这个不常用
const getInfo = new Function()
// 最后就是函数的调用
getInfo();
// 4. 返回值
// js的函数默认只能返回一个值
// 当然,有人说函数yeild可以返回多次,那个后边章节另说
function getInfo (name) {
return name
}
python函数:
# python函数的创建 略有不同
# 1. 首先关键字不同,不再是 function, 而是 def
# 2. 命名方式不同,不再是驼峰,而是下划线分隔
# 3. 函数体不同,不再是花括号,而是冒号和缩进
# 主要就是以上三个区别
# 下边定义一个函数感受一下python的函数定义
def get_info (name):
print('hello' + name)
# 函数的调用方式相同
get_info('Will');
# 函数可以返回多个值
def get_info(name, age, gender):
return name,age,gender
# 最终可以输出几个值 而且注意输出的值的类型是元组(就是元素不可更改的数组)
函数的参数
js函数的参数:
// js参数
// 1. 形参实参
function getInfo (name) {
return 'hello, ' + name
}
// name 就是函数的形参
// 执行的时候 需要传入实际参数,否则就会输出undefined
getInfo('Will');
// 2. 默认参数
function getInfo(name='Will') {
return 'hello, ' + name
}
// 默认约定一个参数,如果不传递参数,就会显示默认参数
// 3. arguments 参数伪数组
function getInfo (name, age) {
console.log(arguments)
}
// 参数
getInfo('Will', 30) // 结果输出一个伪数组 ['Will',30]
// 注意 arguments可不是数组,是一个伪数组,所以不能使用数组原型链上的方法
// 4. 剩余参数 rest
function getInfo (name, ...rest) {
console.log(rest)
}
// 传入参数
getInfo('Will', 10, 'hehe', 'haha'); // [10, 'hehe', 'haha']
// 注意,和arguments不同,rest可是一个实打实的数组,可以使用数组原型链上的所有方法
python函数的参数:
# python 参数分的相对比较细致
# 1. 形参 这和js相同,直接写参数就好
def get_info (name, age):
# 2. 默认参数 这也和js系统
def get_info(name, age=30):
# 3. 可选参数 几乎等同于js的rest(剩余参数)返回也是一个数组(确切说是元组,不可修改的数组)
def get_info (*args):
print(args)
get_info('Will', 30, 'male', 'HeNan')
# args 最终就是 一个元素 ('Will', 30, 'male', 'HeNan')
# 既然是数组 就可以使用数组的方法——遍历,请注意 他不能修改,
# 除非强制转换为普通列表,比如 list(args)
# 4. 关键字参数 **kwargs
# 这个是python区别于js的函数的地方
# 他的返回一个字典(对象)
def get_info (**kwargs):
print(kwargs)
# 调用的时候需要写成key=value形式
# 开始调用
get_info(name='Will', age=30, gender='male')
# 最终可以得到这个关键字参数是一个 字典(就是得到一个对象形式的参数集合),如下
{'name': 'Will', 'age': 30, 'gender': 'male'}
函数的模块化
js的模块化:
// js的模块化
// 必须在比较新的浏览器版本中可以支持或者使用babel等转义工具
// js模块化主要三种
// 1. ES6 ESmoudle —— import export(default)
// 具体形式就是: import 包名 from '路径'
// 这种模式目前在开发中使用较多
// 比如在 a.js 中定义了一个函数
export const getInfo = (name, age) => {
}
// 可以在b.js 中导入该模块进行使用
import { getInfo } from './a.js'
getInfo('Will', 30)
// 2. commonjs规范 require moudle.exports 主要在nodejs中用的比较多
// 比如在a.js 导出一个包
module.exports = {
getInfo : function () {}
}
// 在 b.js 中引入
const A = require('./a.js')]
A.getInfo()
// 3. 还有其他的模块方案 比如 AMD CMD, 都有其最佳的实现方案,在此不再赘述,因为如今项目,使用以上两种就够了
python的函数导包:
# python的导包没那么规范,但是形式和js略有不同
# 基本的格式和js相反: from 包名 import 模块
# 引入内置库或者第三方库 比如 导入时间库
import time
t=time.gmtime()
print(time.strftime("%Y-%m-%d %H:%M:%S",t))
# 最终输出 2023-07-19 06:06:25
# 比如引入自定义模块
# a.py
def get_name (name):
print(name)
# 在 b.py 中使用
from a import get_name
get_name('Will') # 输出 Will
当然,导包的过程中还可以给导入的模块起个别名:
from a import get_info as g_i。
许多用法实际开发中,会逐步遇到,在此不再赘述。
高阶函数
无论在js还是python,对于高阶函数的定义都是一致的:一个函数,它的参数是一个函数或者它的返回值是一个函数,那么这个函数就是高阶函数。
js高阶函数:
// js高阶函数
// 1. 内置的高阶函数
// js中有很多函数,经常被使用,它们都是内置函数
// 比如数组的map, filter, find等等
let a = [1,2,3,4,5];
// 将一个数组的每一项都乘以10
let b = a.map(
function (num) {
return num * 10
}
)
// 2. 自定义高阶函数
// 比如 函数的柯里化
function add (x) {
return function (y, z) {
return x + y + z
}
}
// 柯里化的优点就是 提前初始化函数 内置一些变量
const fn = add(10);
fn(1,2) // 最终结果 10 + 1 + 2 = 13
python的高阶函数:
# python的高阶函数
# 1. 内置了很多的高阶函数
# 还是拿list的map函数说起吧
# 定义一个函数 函数的功能是将每一项最终输出它的平方
def sq(n):
return n**2
# 使用map函数 传入上边定义的函数
r = map(sq, [1, 2, 3, 4, 5])
# 需要注意的是python的map函数始终返回一个 迭代器, 所以需要转换为 list
print(list(r)) # -> [1, 4, 9, 16, 25]
# 2. 来一个比较综合的案例
# 使用 filter函数和lambda 生成一个新的list
# 首先使用lambda创建一个函数: 输出偶数
fn = lambda(x: x % 2 ==0)
# 再使用推导式生成一个list
l1 = [i for i in range(1,10)])
# 最终使用filter函数过滤 偶数
l2 = filter(fn, l1)
# 需要注意的是, 和 map函数相同, filter也返回一个迭代器,所以需要手动转换为list
print(list(l2))
# 3. 自定义高阶函数
# 写一个求和函数
def lazy_sum(*args):
def sum():
ax = 0
for num in args:
ax += num
return ax
return sum
# 创建一个函数 接收返回的函数 (闭包 和js概念一摸一样)
f1 = lazy_sum(1, 2, 3, 4, 5)
print(f1())
至此,函数的一个基本理解和认识已经结束。当然,深入理解当然远远不止这些。
入门的话基本够用了。
第二课到此结束。
版权声明:本文为jmszl1991原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。