Python-100-Days: Day06 Functions and Modules

news2024/11/25 13:25:47

 函数的作用

编程大师Martin Fowler先生曾经说过:“代码有很多种坏味道,重复是最坏的一种!”,要写出高质量的代码首先要解决的就是重复代码的问题。可以将特定的功能封装到一个称之为“函数”的功能模块中,在需要的时候,我们只需要“调用”这个“函数”就可以了。

定义函数

在Python中可以使用def关键字来定义函数,和变量一样每个函数也有一个响亮的名字,而且命名规则跟变量的命名规则是一致的。在函数名后面的圆括号中可以放置传递给函数的参数,这一点和数学上的函数非常相似,程序中函数的参数就相当于是数学上说的函数的自变量,而函数执行完成后我们可以通过return关键字来返回一个值,这相当于数学上说的函数的因变量。

原始程序:

"""
输入M和N计算C(M,N)

Version: 0.1
Author: Maxwell
"""
m = int(input('m = '))
n = int(input('n = '))
fm = 1
for num in range(1, m + 1):
    fm *= num
fn = 1
for num in range(1, n + 1):
    fn *= num
fm_n = 1
for num in range(1, m - n + 1):
    fm_n *= num
print(fm // fn // fm_n)

对上述代码进行重构,在不影响代码执行结果的前提下对代码结构进行调整,重构后的代码如下:

"""
输入M和N计算C(M,N)

Version: 0.1
Author: Maxwell
"""
def fac(num):
    """求阶乘"""
    result = 1
    for n in range(1, num + 1):
        result *= n
    return result


m = int(input('m = '))
n = int(input('n = '))
# 当需要计算阶乘的时候不用再写循环求阶乘而是直接调用已经定义好的函数
print(fac(m) // fac(n) // fac(m - n))

函数的参数

函数是绝大多数编程语言中都支持的一个代码的"构建块",但是Python中的函数与其他语言中的函数还是有很多不太相同的地方,其中一个显著的区别就是Python对函数参数的处理。在Python中,函数的参数可以有默认值,也支持使用可变参数,所以Python并不需要像其他语言一样支持函数的重载,因为我们在定义一个函数的时候可以让它有多种不同的使用方式,下面是两个小例子。

 

from random import randint


def roll_dice(n=2):
    """摇色子"""
    total = 0
    for _ in range(n):
        total += randint(1, 6)
    return total


def add(a=0, b=0, c=0):
    """三个数相加"""
    return a + b + c


# 如果没有指定参数那么使用默认值摇两颗色子
print(roll_dice())
# 摇三颗色子
print(roll_dice(3))
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
# 传递参数时可以不按照设定的顺序进行传递
print(add(c=50, a=100, b=200))

上面两个函数的参数都设定了默认值,意味着如果在调用函数的时候如果没有传入对应参数的值时将使用该参数的默认值,在上面的代码中我们可以用各种不同的方式去调用add函数,这跟其他很多语言中函数重载的效果是一致的。

其实上面的add函数还有更好的实现方案,在不确定参数个数时候,可以使用以下代码:

# 在参数名前面的*表示args是一个可变参数
def add(*args):
    total = 0
    for val in args:
        total += val
    return total


# 在调用add函数时可以传入0个或多个参数
print(add())
print(add(1))
print(add(1, 2))
print(add(1, 2, 3))
print(add(1, 3, 5, 7, 9))

用模块管理函数

对于任何一种编程语言来说,给变量、函数这样的标识符起名字都是一个让人头疼的问题,因为我们会遇到命名冲突这种尴尬的情况。最简单的场景就是在同一个.py文件中定义了两个同名函数,由于Python没有函数重载的概念,那么后面的定义会覆盖之前的定义,也就意味着两个函数同名函数实际上只有一个是存在的。

def foo():
    print('hello, world!')


def foo():
    print('goodbye, world!')


# 下面的代码会输出什么呢?
foo()

当然上面的这种情况我们很容易就能避免,但是如果项目是由多人协作进行团队开发的时候,团队中可能有多个程序员都定义了名为foo的函数,那么怎么解决这种命名冲突呢?答案其实很简单,Python中每个文件就代表了一个模块(module),我们在不同的模块中可以有同名的函数,在使用函数的时候我们通过import关键字导入指定的模块就可以区分到底要使用的是哪个模块中的foo函数,代码如下所示。

module1.py

def foo():
    print('hello, world!')

module2.py

def foo():
    print('goodbye, world!')

test.py

from module1 import foo

# 输出hello, world!
foo()

from module2 import foo

# 输出goodbye, world!
foo()

function1.py

 

"""
函数的定义和使用 - 计算组合数C(7,3)

Version: 0.1
Author: Maxwell
Date: 2024-04-29
"""

def factorial(n):
    result = 1
    for num in range(1, n+1):
        result *= num
    return result


print(factorial(7) // factorial(3) // factorial(4))

 function2.py

"""
函数的定义和使用 - 求最大公约数和最小公倍数

Version: 0.1
Author: Maxwell
Date: 2024-04-29
"""

def gcd(x, y):
    if x > y:
        (x, y) = (y, x)
    for factor in range(x, 1, -1):
        if x % factor == 0 and y % factor == 0:
            return factor
    return 1

def lcm(x, y):
    return x * y // gcd(x, y)

print(gcd(15, 27))
print(lcm(15, 27))

 

function3.py

 

"""
Python的内置函数
- 数学相关: abs / divmod / pow / round / min / max / sum
- 序列相关: len / range / next / filter / map / sorted / slice / reversed
- 类型转换: chr / ord / str / bool / int / float / complex / bin / oct / hex
- 数据结构: dict / list / set / tuple
- 其他函数: all / any / id / input / open / print / type

Version: 0.1
Author: Maxwell
Date: 2024-04-29
"""

def myfilter(mystr):
    return len(mystr) == 6

# help()
print(abs(-1.2345))
print(round(-1.2345))
print(pow(1.2345, 5))
fruits = ['orange', 'peach', 'durian', 'watermelon']
print(fruits[slice(1, 3)])
fruits2 = list(filter(myfilter, fruits))
print(fruits)
print(fruits2)

function4.py

"""
Python常用模块
- 运行时服务相关模块: copy / pickle / sys / ...
- 数学相关模块: decimal / math / random / ...
- 字符串处理模块: codecs / re / ...
- 文件处理相关模块: shutil / gzip / ...
- 操作系统服务相关模块: datetime / os / time / logging / io / ...
- 进程和线程相关模块: multiprocessing / threading / queue
- 网络应用相关模块: ftplib / http / smtplib / urllib / ...
- Web编程相关模块: cgi / webbrowser
- 数据处理和编码模块: base64 / csv / html.parser / json / xml / ...

Version: 0.1
Author: Maxwell
Date: 2024-04-29
"""

import time
import shutil


seconds = time.time()
print(seconds)
localtime = time.localtime(seconds)
print(localtime)
print(localtime.tm_year)
print(localtime.tm_mon)
print(localtime.tm_mday)
asctime = time.asctime(localtime)
print(asctime)
strtime = time.strftime('%Y-%m-%d %H:%M:%S', localtime)
print(strtime)
mydate = time.strptime('2018-1-1', '%Y-%m-%d')
print(mydate)

 function5.py

 

"""
函数的参数
- 位置参数
- 可变参数
- 关键字参数
- 命名关键字参数

Version: 0.1
Author: Maxwell
Date: 2024-04-29
"""


# 参数默认值
def f1(a, b=5, c=10):
    return a + b * 2 + c * 3


print(f1(1, 2, 3))
print(f1(100, 200))
print(f1(100))
print(f1(c=2, b=3, a=1))


# 可变参数
def f2(*args):
    sum = 0
    for num in args:
        sum += num
    return sum


print(f2(1, 2, 3))
print(f2(1, 2, 3, 4, 5))
print(f2())


# 关键字参数
def f3(**kw):
    if 'name' in kw:
        print('欢迎你%s!' % kw['name'])
    elif 'tel' in kw:
        print('你的联系电话是: %s!' % kw['tel'])
    else:
        print('没找到你的个人信息!')


param = {'name': 'Maxwell', 'age': 26}
f3(**param)
f3(name='Maxwell', age=26, tel='18766778899')
f3(user='Maxwell', age=26, tel='18766778899')
f3(user='Maxwell', age=26, mobile='18766778899')

function6.py

"""
作用域问题

Version: 0.1
Author: Maxwell
Date: 2024-04-29
"""

# 局部作用域
def foo1():
    a = 5

foo1()
# print(a)  # NameError

# 全局作用域
b = 10

def foo2():
    print(b)

foo2()

def foo3():
    b = 100     # 局部变量
    print(b)

foo3()
print(b)

def foo4():
    global b
    b = 200     # 全局变量
    print(b)

foo4()
print(b)

倘若您觉得我写的好,那么请您动动你的小手粉一下我,你的小小鼓励会带来更大的动力。Thanks.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1633702.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript代码挑战#4

// 编程挑战 #4 /* 朱莉亚和凯特仍在研究狗,这次她们研究的是狗是否吃得太多或太少。 吃得太多意味着狗当前的食物份量比推荐份量大,吃得太少则相反。 吃得适量意味着狗当前的食物份量在推荐份量的正负 10% 的范围内(参见提示)。 …

企业邮箱哪个性价比高?2024年国内五大企业邮箱功能、价格对比

对于企业来说,更换企业邮箱的成本很高,包括企业邮箱数据迁移,新的通讯录导入等,都会耗时耗力。那么选择能稳定且性价比高的企业邮箱就至关重要,国内的Zoho Mail企业邮箱、网易企业邮箱、阿里企业邮箱、腾讯企业邮箱和新…

2024年宠物行业未来发展趋势(宠物行业增长风口深度报告)

近期,小红书联合第一财经发布了宠物行业洞察报告。报告中指出了宠物行业的三大消费新趋势:科学养宠、专宠专用和双向奔赴。而实际上,这三大趋势在2024年已经有明显的凸显。 趋势一:科学养宠 科学养宠主要体现在宠物主粮的选择上&…

Linux进程概念(七):进程替换 自主shell的编写

目录 进程替换 六种替换函数 自主shell的编写 shell解析命令行字符串的过程 创建makefile 打印输出命令行 获取与分割命令行字符串 多次执行命令 完善工作 完整代码 进程替换 原因:fork创建子进程后,执行的是和父进程相同的代码,…

Spring6 当中 获取 Bean 的四种方式

1. Spring6 当中 获取 Bean 的四种方式 文章目录 1. Spring6 当中 获取 Bean 的四种方式每博一文案1.1 第一种方式:通过构造方法获取 Bean1.2 第二种方式:通过简单工厂模式获取 Bean1.3 第三种方式:通过 factory-bean 属性获取 Bean1.4 第四种…

一例MFC文件夹病毒的分析

概述 这是一个MFC写的文件夹病毒,通过感染USB设备传播,感染后,会向c2(fecure.info:443)请求指令来执行。 样本的基本信息 Verified: Unsigned Link date: 19:52 2007/7/5 MachineType: 32-bit MD5: 4B463901E5858ADA9FED28FC5…

基于SpringBoot+Vue笔记记录分享网站设计与实现

项目介绍: 信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代…

Docker-Compose单机多容器应用编排与管理

前言 Docker Compose 作为 Docker 生态系统中的一个重要组件,为开发人员提供了一种简单而强大的方式来定义和运行多个容器化应用。本文将介绍 Docker Compose 的使用背景、优劣势以及利用 Docker Compose 简化应用程序的部署和管理。 目录 一、Docker Compose 简…

闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子

前言 一个在实际应用中 EF Core 集成 FluentValidation 进行数据校验的例子。 Step By Step 步骤 创建一个 Asp.Net Core WebApi 项目 引用以下 Nuget 包 FluentValidation.AspNetCore Microsoft.AspNetCore.Identity.EntityFrameworkCore Microsoft.EntityFrameworkCore.Re…

leetcode51.N皇后(困难)-回溯法

思路 都知道n皇后问题是回溯算法解决的经典问题,但是用回溯解决多了组合、切割、子集、排列问题之后,遇到这种二维矩阵还会有点不知所措。 首先来看一下皇后们的约束条件: 不能同行不能同列不能同斜线 确定完约束条件,来看看究…

【Linux】yum、vim

🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343🔥 系列专栏:https://blog.csdn.net/qinjh_/category_12625432.html 目录 Linux 软件包管理器 yum 什么是软件包 查看软件包 如何安装软件 如何卸载软…

Apache Seata基于改良版雪花算法的分布式UUID生成器分析1

title: Seata基于改良版雪花算法的分布式UUID生成器分析 author: selfishlover keywords: [Seata, snowflake, UUID] date: 2021/05/08 本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 Seata基于改良版雪花算法的分布式UUID生成器分析…

浅析扩散模型与图像生成【应用篇】(十八)——ControlNet

18. Adding Conditional Control to Text-to-Image Diffusion Models 现有的文生图模型如Stable Diffusion通常需要人工输入非常准确的提示词,而且生成的结果还是完全随机不可控制的,只能通过生成多个结果,再从中选取最佳方案。而ControlNet的…

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现高并发服务器(Http测试板块)

【项目】仿muduo库One Thread One Loop式主从Reactor模型实现高并发服务器(Http测试板块) 一、使用Http网页界面1、main.cc原码和index.html原码2、运行结果(1)测试结果1:用index.html内部的代码(2&#xf…

JSON.toJSONString() 输出 “$ref“:“$[0]“问题解决及原因分析

一、背景 在构建一个公共的批处理方法类的时候,在测试输出的时候,打印了" r e f " : " ref":" ref":"[0][0]"的内容,这让我比较疑惑。不由得继续了下去… 二、问题分析 首先,我们需要…

MySQL Binlog 闪回与分析

文章目录 前言1. 修改 event 实现闪回1.1 binlog 结构1.2 闪回案例1.3 方法总结 2. 解析文本闪回2.1 mysqlbinlog2.2 闪回案例2.3 方法总结 3. 在线订阅闪回3.1 mysql-replication3.2 binlog2sql3.3 方法总结 4. Binlog 分析方法4.1 分析场景4.2 辅助定位事务4.3 方法总结 5. 平…

性能监控之prometheus+grafana搭建

前言 Prometheus和Grafana是两个流行的开源工具,用于监控和可视化系统和应用程序的性能指标。它们通常一起使用,提供了强大的监控和数据可视化功能。 Prometheus Prometheus是一种开源的系统监控和警报工具包。它最初由SoundCloud开发,并于…

基于SSM+Jsp+Mysql的汽车租赁系统的设计与实现

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包…

Python爬虫(入门版)

1、爬虫是什么 简单的来说:就是用程序获取网络上数据。 2、爬虫的原理 如果要获取网络上数据,我们要给爬虫一个网址(程序中通常叫URL),爬虫发送一个HTTP请求给目标网页的服务器,服务器返回数据给客户端&am…

Linux详解:进程等待

文章目录 进程等待等待的必要性进程等待的方法waitwaitpid获取子进程status阻塞等待 与 非阻塞等待 进程等待 等待的必要性 子进程退出,父进程不进行回收的话,就可能造成僵尸进程,进而造成内存泄露 如果进程进入了僵尸状态,kill…