函数的使用
# 1. 内容本文旨在介绍Python的学习思维,不必局限于文中将要介绍的函数,装饰器等概念。
文中环境为 python3, ipython中运行
# 2. 要求
要求已了解Python基本语法,基本数据结构和内置函数,[广告](https://www.52pojie.cn/thread-718631-1-1.html "Python数据分析基础文档")
# 3. 废话
本人技术有限,敬请指教。
喜欢逛影视推荐区,发现权限不够了,故有此文。
***坛友给仨热心,就要仨!***
# 4. 函数
## 函数是什么
**函数使用来封装代码的,再通俗点,一个函数就是一个功能。**
## 怎么创建函数
**格式**
```
def 函数名([参数1, ...):
"""使用说明
"""
函数体(代码写在这里)
```
来做下解释:
* 方括号表示可选
* 函数名与变量名定义要求一致,字母,数字,下划线,(允许中文,但不建议),需以下划线或字母开头哦
* 使用说明是可选的
* return语句是用来返回函数这个功能的结果,(程序是专门用来计算和处理东西的,所以返回值就是功能的计算结果或处理结果)
好,让我们步入正题
### 1. 无参函数
我们先来举第一个例子,函数功能为 ***获取一个有8个0的列表***
先来看看不用函数时的实现与使用:生成与打印
```
lst8_1 = * 8# 第一行有8个0
print(lst5_1)
```
我们要使用函数了
```
def create_lst8():
"""生成5个0的列表
"""
lst8_1 = * 8
return lst8_1
lst8_1 = create_lst8()
print(lst8_1)
```
这么一看,使用函数貌似更麻烦了,请耐心看下去
### 2. 有参函数及默认参数
需求变了,我们想要有10个或更多个的数字0列表怎么办,第一种没有使用函数的实现就会很麻烦,我们来看函数的实现
```
def create_lst(n):
"""n可指定列数
"""
lst = * n# 注意此处列表乘法的限制,n必须为整数,否则会异常的哟,请自行学习异常处理
return lst
lst = create_lst8(8)
print(lst)
```
可以看到,如果我们不使用函数也是可以的,把函数体内代码拿出来,n改为你想要的列数。
但是,函数的另一个作用就是 **复用**,也就是这个函数我们可以在任意声明它的位置使用,只要其参数n改变,就可以获取到相应的列表,而不使用函数,你就需要再写一遍。嗯~有点啰嗦了。
** 参数可以有多个,并且可以有默认参数 **
```
def create_lst(tmp, n=8):
"""n可指定个数
"""
print(tmp)# tmp是我用来帮大家理解函数参数格式的,没有作用
lst = * n
return lst
lst = create_lst(1000)# 存在默认参数的情况下,我们可以省略有默认值的n参数,而tmp没有默认值,所以必须要传值
print(lst)
```
有多个参数时定义函数,注意:
* 有默认值的参数需要定义在后面,比如 n=8 要写在 tmp 后
有多个参数时使用函数,注意:
* 不写参数名需要参数位置对应,比如上面的函数 create_lst(1000, 10), 在函数内 tmp就是1000,n就是8
* 写参数名可以任意调整位置,比如上面的函数 create_lst(n=10, tmp=1000)
### 3. 可变参
大家可能见过这种形式的函数定义
```
def create_lst(*args, **kwargs):
"""
args 会接收所有没有写参数名的参数,以列表形式呈现
kwargs 会接收所写了参数名的参数,以字典形式呈现
"""
lst = * kwargs['n']
return lst
lst = create_lst(1000, n=10)# 注意此时,在函数内部 args 为 ,kwargs 为 {'n': 10}
print(lst)
```
这种形式的函数定义要做好参数的判断,因为如果参数n没有作为函数参数,上述调用就会报错了。
多写代码理解哦
### 4. 拆箱(并非C#对象中的拆箱概念) - 函数调用的黑科技
Python 支持这种语法
```
a, b = 1, 2# 赋值 a = 1, b = 2
a, b = # 赋值 a = 1, b = 2
a, *b = # 我擦 a = 1, b = ,是不是跟3.可变参有点像
```
我们反过来,现在有个变量 `vars_1 = ` 就是tmp和n,怎么传给函数呢
```
create_lst(vars_1, vars_1)# 没错,这是传统的写法
create_lst(*vars_1)# create_lst(vars_1, vars_1)
```
对于字典 `vars_2 = {'tmp': 1000, 'n': 10}`
```
create_lst(**vars_2)# 我擦!!create_lst(tmp=1000, n=10)
```
貌似有点绕,多写代码看看效果,告诉大家一个用来理解的笨方法,不知道是什么东西的变量就使用print输出一下
### 5. 返回值
注意:不写return,相当于在函数结束有个 return None
# 5. 装饰器
**装饰器是个什么东东**
一句话,Python中一切都是对象,通俗一点,装饰器可以用来扩展函数的功能
既然函数也是对象,那函数也可以作为函数的参数和返回值,如下
```
def call_func(func):
print('函数%s被调用了' % func.__name__)
return func# 此处原封不动的返回func函数
create_lst = call_func(create_lst)# 然而效果并不好,只是体现了 *函数可以作为参数和返回*
```
来看装饰器,create_lst函数不是要求n为整数吗,我们使用装饰器给这个函数加上数据验证功能
```
def arg_check(func):
"""arg_check就是装饰器
"""
def wraper(*args, **kwargs):
"""wraper是参数func函数的替代品
"""
n = kwargs.get('n)# 获取n的值,注意,我们从kwargs中获取n,就需要参数n以命名参数的形式传入
if not isinstance(n, int) or n<3:
print('警告:n取值无效,已设为默认值8')
n = 8# 如果n不是整数或者n小于3,则将n设为默认8
ret = func(n=n)# 将已验证的参数传入我们的原始函数
return ret
return wraper# 装饰器返回包装函数wraper,大家可以自己理解一下调用时的运行流程
@arg_check# 使用装饰器定义函数
def create_lst(*args, **kwargs):
"""
args 会接收所有没有写参数名的参数,以列表形式呈现
kwargs 会接收所写了参数名的参数,以字典形式呈现
"""
lst = * kwargs['n']
return lst
#create_lst = arg_check(create_lst)# 上面的定义相当于此句。理解一下,其实赋值符号左边的函数是包装函数wraper
create_lst(n=None)# 此时函数依然可运行,可以思考一下会返回什么
```
还会有有参装饰器,上面的装饰器已经将n的默认值固定为8,我们可以通过装饰设置n的默认值
```
def arg_check(func, n=8):
"""arg_check就是装饰器
"""
def wraper(*args, **kwargs):
"""wraper是参数func函数的替代品
"""
number = kwargs.get('n)# 防止作用域问题
if not isinstance(number, int) or number<3:
print('警告:n取值无效,已设为默认值8')
number = n# 如果n不是整数或者n小于3,则将n设为默认8
ret = func(n=number)# 将已验证的参数传入我们的原始函数
return ret
return wraper# 装饰器返回包装函数wraper,大家可以自己理解一下调用时的运行流程
@arg_check(n=10)# 使用装饰器定义函数,n的默认值为10
def create_lst(*args, **kwargs):
"""
args 会接收所有没有写参数名的参数,以列表形式呈现
kwargs 会接收所写了参数名的参数,以字典形式呈现
"""
lst = * kwargs['n']
return lst
```
装饰器差不多就结束了
***ps. 学习Python装饰器的同时,大家也可以了解一下闭包***
# 6. 作用域
上面提到了作用域,函数作用域是指 函数内部定义的变量,在函数外是无效的
```
def func(n):
a = 0
```
上述函数,func作用域内有两个变量,n和a
* a在函数外是没有的,所以函数外部获取不到a的值
* n有点麻烦,涉及传入的对象还是值,也就是c语言中的传引用与传值,传值时对n的修改是不影响外部的,而传对象时对n进行修改,外部的传来的这个变量也会随之更改(有点绕)。基本数据类型好像都是传值形式(int, str, float, bool等),对象类型有tuple(不可更改哟),list,set,dict,以及类对象
再来看代码
```
a = 0
n =
def func(a, n):
a = 1# 这个是不影响函数外部的那个a的
print(a)
n = 0# 注意我们给n传递一个列表
print(n)
func(a, n)# 此时将函数外部的a, n传递到函数内部
print(a)# 0# a是基本类型,使用值传递,不影响外部
print(n)# # n是列表,使用引用传递,对n更改外部的值也改变
```
# 7. 内置函数
我们先用ipython来看看python的内置函数,不得不说,这些函数都能用到的
```
dir(__builtin__)
# ...略...
# 'abs',# 取绝对值
# 'all',# 可迭代对象内部元素是否全为True(不是布尔类型的进行转为bool)
# 'any',# 可迭代对象内部元素是否含有True
# 'ascii',# 返回参数的ascii码 ascii('中国') -> '\\u4e2d\\u56fd'
# ...略...
```
dir是一个内置函数,用来获取参数对象的属性,而__builtin__是python环境启动时就会导入的模块,内置函数都是在__builtin__中的。先理解到此处即可。
我们该如何了解怎么使用这些内置函数呢?是的,help!!!
```
help(abs)# help也是内置函数,help(abs)就是查看abs函数的帮助文档,篇幅有限,abs就是取绝对值函数,具体帮助请自行查看输出
```
先写这么多吧。 我组织语言能力有限,写的可能有点乱,请多指出不足之处 支持一下,感谢分享
页:
[1]