python fun_Python 基本功: 7. 介绍函数

在开始介绍函数之前,请大家回顾一下之前的两篇教程:多多教Python:Python 基本功: 5. 数据序列化​zhuanlan.zhihu.com多多教Python:Python 基本功: 6. 第一个完整的程序​zhuanlan.zhihu.com

在跟着上面两篇教程完成了第一个完整的程序,并且成功运行之后,现在我们来开始真正的学习 Python 这一门语言。计算机语言是一门艺术,而 Python 的艺术魅力从函数(Function) 开始展开。

教程需求:Mac OS (Windows, Linux 会略有不同)

安装了 Python 3.0 版本以上, PyCharm

函数 Function

首先介绍一下什么是Python中的函数,其实很简单,看一段代码就明白了:一个 python 函数 fun

一个 Python 函数有以下元素,和上图代码一一对应:Define (定义): 第一行 def 关键词就是用来定义一个函数的名字,名字叫 "fun"。

Parameters (参数): a, b 是函数的两个参数。

Scope (范围): 实现函数具体内容的区间,在第一行的冒号 ":" 之后开始,以 return 结束。

Description (介绍): 这个是可有可无的,具体的对函数的介绍,之后会详细讲到如何写。

Implementation (实现): 这是函数具体做的事情,在上图就是第8,9行,函数把a, b两个参数相加,并且回复。

Return (回复): 函数结束之后回复的内容,可以不回复,默认回复 None。

Python 函数还有其他元素,当然在基础篇里了解这几个就足够了。那为什么我们需要函数,而不是直接实现其内部的方法呢?比较下面:

c = a + b

同样的把两个数值相加,不用函数可以一行写完,但是用了函数却要9行,显得很麻烦。但是我们来看下面这个例子:

def fun(a, b):

if a + b == 0:

return 0

else:

return a * (a - b) / (a + b)

c = fun(1, -1) + fun(10, -9)

这里函数做的事情是先比较 a+b 是不是等于0,如果等于0回复0,否则回复一个复杂的计算。这里虽然我们还没有讲到 Python 的逻辑方法,但是 if...else... 语句我相信还是很明了的。这里的函数做的事情是把一个比较冗长的事情囊括起来,然后提供了一个简明的界面(Interface) 来传入参数并且支持反复调用。不过记得如果要调用一个函数,这个函数需要在调用之前已经被定义并且实现。这句话可能现在难以理解,不需要担心,在之后的关于 抽象函数 (Abstract Function) 就会再次讲解。

函数还是变量?

函数可以是变量,但是只有函数可以被调用,而变量不可以,但是变量可以索引 (之后会讲到):

( )

[ ]

现在我们来看之前学过的字典,参考多多教Python:Python 基本功: 3. 数据类型 和这里新学的函数做一个比较:

def fun_abc(date):

return len(str(date))

fun_dict = {'2019/10/21': 122}

fun_abc('2019/10/21')

fun_dict['2019/10/21']

这里先定义了一个函数 fun_abc, 这个函数数传入的 date 参数在转换成字符串以后有多少个字符,返回的是一个整数。而后创建了一个字典,里面的 Key 是字符串的日期,Value 是价格。在调用函数 fun_abc 的时候,用的是 "( )" 并且传入参数,而字典变量虽然也传入了同样的参数,但是用的是字典的索引 "[ ]"。你可以尝试替换 "( )" 和 “[ ]” ,看看 Python 的报错结果。

函数在定义完了之后,也可以当做一个变量传入另一个函数中。这句话比较绕口,但是我们来举个例子就明白了:

def fun_add(a, b):

return a+b

def fun_subtract(a, b):

return a-b

def fun_non_negative(a, b, operation):

ret = operation(a, b)

return max(0, ret)

c = fun_non_negative(-9, -8, fun_subtract)

# c = ???

这里 c 是多少呢? 答案是 0,现在我们来解释一下:一开始,我们定义了一个加法函数, fun_add,比较简单。

随后,我们定义了一个减法函数,fun_subtract, 同样也不复杂。

然后我们定义了一个新的函数, non negative 的意思是没有负数。这个函数传入三个参数,第一第二个是数值,第三个是一个可以通过 "()" 调用的函数,函数内部的第一行就是通过 "()" 传入了a, b 两个参数。整个函数做的事情就是先对a, b 进行运算,然后在回复之前确保数值是大于0的,否则回复0。

给 __main__ 添加函数

现在我们回到上一个教程,多多教Python:Python 基本功: 6. 第一个完整的程序, 在写完的第一个程序里利用函数把核心逻辑囊括起来,看看是否在程序结构上显得更加清晰:

# file: intro_to_function.py

# author: DDTeachPython

from datetime import datetime

import json

import sys

def report_daily_price(ticker, input_file, report_date=""):

"""汇报每日价格:param ticker: 股票符号:param input_file: 读取文件:param report_date: 汇报日期:return: ret_dict: 回复一个字典数据"""

ret_dict = dict()

with open(input_file, 'r') as file_to_read:

for line in file_to_read.readlines():

# 逗号是分隔符,Delimiter

date_str, price_str = line.split(',')

# 读取的字符串,转换成对应的数据类型

dt = datetime.strptime(date_str, '%m/%d/%Y')

price = float(price_str)

# 数据存入字典,以之后调用

ret_dict[dt] = price

# 计算高低价格,回报率

max_price = max(ret_dict.values())

min_price = min(ret_dict.values())

ret_pcnt = (ret_dict[datetime(2019, 7, 18)] - ret_dict[datetime(2019, 7, 10)]) / ret_dict[datetime(2019, 7, 18)]

# 创建报告字典

output_dict = dict()

output_dict['Title'] = ticker + " Price Report"

output_dict['Max Price'] = str(max_price)

output_dict['Min Price'] = str(min_price)

output_dict['Return %'] = "{:.2f}".format(ret_pcnt * 100) + "%"

# 写入文件

report_file = ticker + '_report' + "_" + report_date + '.json'

with open(report_file, 'w') as file_to_write:

json.dump(output_dict, file_to_write)

return ret_dict

if __name__ == '__main__':

# 报告文件名

if len(sys.argv) > 1:

report_date = sys.argv[1]

else:

report_date = ""

abc_file = 'abc_date_price.txt'

abc_dict = report_daily_price(ticker='ABC', input_file=abc_file, report_date=report_date)

print(abc_dict)

这里大部分代码逻辑和前文是一样的,只是创建了一个新的函数,然后把逻辑搬到了函数内部。这里的函数 report daily price 里的第三个参数有一个默认数值为空 report_date=""。意思是如果在运行程序的时候参入的参数为空,那么函数就会默认给 report_date 一个空的字符串。在 PyCharm 里运行程序的时候,通过下面这个方法传入参数:PyCharm 传入参数

点右上方的 intro_to_python 的文件名,然后下拉 edit configuration, 进入之后在红框中的 Parameters 栏里填上传入的日期,就可以在每次运行的时候传入这个参数。

虽然这么操作并没有优化处理数据的方式,而且大部分代码只是转移到了函数内部。但是在大多数 Python 程序中,进入 main() 之后会有6大步骤 (见下图),而通过把核心逻辑函数区分开定义,你就可以更加专注于定义不同的核心逻辑上面,然后在 main() 函数里替换调用就可以了。函数的一个很大的好处就是不用重复写核心逻辑代码

小结

虽然 Python 本身不是函数式编程 (Functional Programming), 但是Python 的函数用得好可以非常6。这里函数只是简单的介绍了一下,还有很多深入的概念将在之后的教程中提到,有兴趣的小伙伴可以先去外部链接学习一下:

外部的一篇教程,里面例子比较多:菜鸟 Python 函数​www.runoob.com

抽象函数的细节,比较深入:abc - Abstract Base Classes - Python 3.8.0 documentation​docs.python.org

Lambda 表达式,是一种匿名函数,之后会教到,但是这里是一篇已经有的教程:python入门基础之lambda匿名函数详解​baijiahao.baidu.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值