吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

搜索
查看: 480|回复: 2

[Python] 函数的使用

  [复制链接]
xinfor 发表于 2019-3-16 14:17

1. 内容

本文旨在介绍Python的学习思维,不必局限于文中将要介绍的函数,装饰器等概念。

文中环境为 python3, ipython中运行

2. 要求

要求已了解Python基本语法,基本数据结构和内置函数,广告

3. 废话

本人技术有限,敬请指教。

喜欢逛影视推荐区,发现权限不够了,故有此文。

坛友给仨热心,就要仨!

4. 函数

函数是什么

函数使用来封装代码的,再通俗点,一个函数就是一个功能。

怎么创建函数

格式
def 函数名([参数1, ...): """使用说明 """ 函数体(代码写在这里) [return 返回值]
来做下解释:

  • 方括号表示可选
  • 函数名与变量名定义要求一致,字母,数字,下划线,(允许中文,但不建议),需以下划线或字母开头哦
  • 使用说明是可选的
  • return语句是用来返回函数这个功能的结果,(程序是专门用来计算和处理东西的,所以返回值就是功能的计算结果或处理结果)

好,让我们步入正题

1. 无参函数

我们先来举第一个例子,函数功能为 获取一个有8个0的列表

先来看看不用函数时的实现与使用:生成与打印
lst8_1 = [0, ] * 8  # 第一行有8个0 print(lst5_1)
我们要使用函数了
def create_lst8(): """生成5个0的列表 """ lst8_1 = [0, ] * 8 return lst8_1 lst8_1 = create_lst8() print(lst8_1)
这么一看,使用函数貌似更麻烦了,请耐心看下去

2. 有参函数及默认参数

需求变了,我们想要有10个或更多个的数字0列表怎么办,第一种没有使用函数的实现就会很麻烦,我们来看函数的实现
def create_lst(n): """n可指定列数 """ lst = [0, ] * n  # 注意此处列表乘法的限制,n必须为整数,否则会异常的哟,请自行学习异常处理 return lst lst = create_lst8(8) print(lst)
可以看到,如果我们不使用函数也是可以的,把函数体内代码拿出来,n改为你想要的列数。

但是,函数的另一个作用就是 复用,也就是这个函数我们可以在任意声明它的位置使用,只要其参数n改变,就可以获取到相应的列表,而不使用函数,你就需要再写一遍。嗯~有点啰嗦了。

参数可以有多个,并且可以有默认参数
def create_lst(tmp, n=8): """n可指定个数 """ print(tmp)  # tmp是我用来帮大家理解函数参数格式的,没有作用 lst = [0, ] * 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 = [0, ] * kwargs['n'] return lst lst = create_lst(1000, n=10)  # 注意此时,在函数内部 args 为 [1000, ],kwargs 为 {'n': 10} print(lst)
这种形式的函数定义要做好参数的判断,因为如果参数n没有作为函数参数,上述调用就会报错了。

多写代码理解哦

4. 拆箱(并非C#对象中的拆箱概念) - 函数调用的黑科技

Python 支持这种语法
a, b = 1, 2  # 赋值 a = 1, b = 2 a, b = [1, 2]  # 赋值 a = 1, b = 2 a, *b = [1, 2, 3]  # 我擦 a = 1, b = [2, 3],是不是跟3.可变参有点像
我们反过来,现在有个变量 vars_1 = [1000, 10] 就是tmp和n,怎么传给函数呢
create_lst(vars_1[0], vars_1[1])  # 没错,这是传统的写法 create_lst(*vars_1)  # create_lst(vars_1[0], vars_1[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 = [0, ]
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 = [0, ]
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 = [1, 2, 3] def func(a, n): a = 1  # 这个是不影响函数外部的那个a的 print(a) n[0] = 0  # 注意我们给n传递一个列表 print(n) func(a, n)  # 此时将函数外部的a, n传递到函数内部 print(a)  # 0  # a是基本类型,使用值传递,不影响外部 print(n)  # [0, 2, 3]  # 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就是取绝对值函数,具体帮助请自行查看输出

先写这么多吧。

免费评分

参与人数 3吾爱币 +2 热心值 +3 收起 理由
微微笑95 + 1 我很赞同!
qxj + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
like钱 + 1 + 1 谢谢你编写的教程 我感觉还是打比方更好一点 这样更容易理解

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| xinfor 发表于 2019-3-16 14:25
我组织语言能力有限,写的可能有点乱,请多指出不足之处
sumu03030 发表于 2019-3-17 10:44 来自手机
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:禁止回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2019-7-20 15:42

Powered by Discuz!

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表