python-day3

news2024/11/14 8:35:39

第003天

函数和模块的使用

定义函数

在python中可以使用def关键字来定义函数,和变量一样每个函数也有一个名字,而且命名规则和变量的命名规则是一致的。在函数名后面的圆括号中可以放置传递给函数的参数,程序中函数的参数就是相当于数学上说的函数的自变量,函数执行完成后可以通过return关键字来返回一个值,这相当于数学上说的函数的因变量。
例:
排列组合,输入M和N计算C(M,N)
有一个经典算法:C(m, n) = (m!) / n! / (m-n)!

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的math模块中其实已经有一个名为factorial函数实现了阶乘运算,事实上求阶乘并不用自己定义函数。

函数的参数

函数是绝大多数变成语言中都支持的一个代码的“构建块”,但是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))

执行结果

2
16
0
1
3
6
350

上面两个函数都设定了默认值,这就意味着如果在调用函数的时候如果没有传入对应参数的值时将使用该参数的默认值,所以在上面的代码中可以使用各种不同的方式去调用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))

执行结果如下:

0
1
3
6
25

*args
*args 不定参数(不定的意思是指,预先并不知道,函数使用者会传递多少个参数给你)
*args是用来发送一个非键值对的可变数量的参数列表给一个函数。
*args的用法:当传入的参数个数未知,且不需要知道参数名称时。

用模块管理函数

由于python中没有函数重载的概念,如果在同一个.py文件中定义了两个同名函数,后面的定义会覆盖之前的定义,也就是意味着两个函数同名函数实际上只有一个时存在的

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

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

foo()

执行结果:

goodbye, world

(精通各种语言写的hello,world)
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()

也可以按照如下所示的方式来区分到底要使用哪一个foo函数
test2.py

import module1 as m1
import module2 as m2

m1.foo()
m2.foo()

输出结果:

hello, world!
goodbye, world!

注意上述代码在引用时,要么是引用该模块化文件以后立即执行该函数,要么就是在引用中利用不同的名字将其区分开,如果按照下面的方式,会导致后导入的foo覆盖之前导入的foo
test3.py

from  module1 import foo
from  module2 import foo

foo()

输出结果:

goodbye, world!

test4.py

from module2 import foo
from module1 import foo

foo()

输出结果:

hello, world!

说明:
如果我们导入的模块除了定义函数之外还有可执行代码,那么python解释器在导入这个模块时就会执行这些代码。事实上我们可能并不希望如此,因此如果我们在模块中编写了执行代码,最好是将这些执行代码放入如下所示的条件中,这样的化除非直接运行该模块,if条件下的这些代码是不会执行的,因为只有直接执行的模块的名字才是"main"
module3.py

def foo():
    pass

def bar():
    pass

# __name__是python中一个隐含的变量,它代表了模块的名字
# 中有被python解释器直接执行的模块的名字才是 __main__
if __name__ == '__main__':
    print('call foo()')
    foo()
    print('call bar()')
    bar()

test5.py

import module3
# 导入module3时,不会执行模块中if条件成立时的代码,因为模块的名字时module3而不是__main__

补充:
1、在python中,凡是以两个下划线开头,两个下划线结尾的变量叫做“魔法变量”,可以简单理解为魔法变量是python对象内置天生就有的属性变量。
首先创建一个名为 demo.py的python文件,里面只有一句代码

print(__name__)

在这里插入图片描述
直接在某个模块打印它自己的__name__属性,值就是__main__,这代表当前模块正在以“直接运行”的方式在运行
接下来,将这个模块导入到别的python文件中(本人创建的为study.py)
study.py

import demo

执行
在这里插入图片描述
当模块A被导入到模块B时,一旦运行模块B,模块A中的语句会自动被执行一遍,以便加载模块A中所有的函数定义、类定义等语句到内存中等待被使用。所以,当运行study.py文件时,其实就相当于自动运行了一次demo.py这个文件,第二点,当模块是以“被导入”的方式运行时,它的__name__属性会自动变成该模块的名字,所以study.py打印出来的是demo。
所以:if name == "main"的含义:
这个if语句只有当这个模块被直接运行时才会满足,当这个模块被导入到别的模块时是不会被满足的。所以,凡是想让某些代码只在当前模块下运行时,就把该模块的代码放在该if语句下面。

练习

1、实现计算最大公约数和最小公倍数的函数

import math

x = int(input('x = '))
y = int(input('y = '))

# 返回最大公约数函数
def max_factor():

    m = max(x, y)
    n = min(x, y)
    r = m % n

    while r != 0:
        m = n
        n = r
        r = m % n
    return n

# 返回最小公倍数
def min_multiple():

    min_num = x * y / max_factor()
    return min_num

print('最大公因数是%d,最小公倍数是%d' % (min_multiple(), min_multiple()))

或者:

def gcd(x, y):
    """求最大公约数"""
    (x, y) = (y, x) if x > y else (x, y)
    for factor in range(x, 0, -1):  
        if x % factor == 0 and y % factor == 0:
            return factor

def lcm(x, f):
    """求最小公倍数"""
    return x * y // gcd(x, y)

求最小公约数见的还挺多的,这里再写一下它的思想吧。
辗转相除法
1)找出两个数的大值和小值
2)定义一个临时变量等于大值%小值
3)重复1)直到临时变量为0,本次计算中的小值就是最大公约数
暴力法
1)找打两个数的大值和小值
2)从小值-1开始循环,步长为-1
3)当大值和小值%某数都为0时,该数为最大公约数
练习2、实现判断一个数是不是回文数的函数

def is_palindrome(num):
    """判断一个数是不是回文数"""
    temp = num
    total = 0
    while temp > 0:
        total = total * 10 + temp % 10
        temp //= 10

    return total == num

算法思想:
回文,是指顺序和反序是一样的。类似于12321、反过来也是12321。这个时候就需要考虑如何将它的每位翻转过来。通过每次取到最低位,并且将每次×10加上新取到的最低位来达到该效果。(num%10可以取到最低位),然后此时不知道它判断多少次,所以选用while循环,每次取了最低位以后需要将该数字除以10,当个位时,它除以10就是0。所以判断条件可以考虑temp > 0。
练习3:实现判断一个数是不是素数的函数

def is_prime(num):
    for x in range(2, int(num ** 0.5) + 1):
        if num % x == 0:
            return False
    return True if num != 1 else False  # 要把1排除

在考虑二元对立的问题时,可以从两个方向出发考虑。不是XX便是XX
练习4、写一个程序判断输入的正整数是不是回文素数

def is_palindrome(num):
    temp = num
    total = 0
    while temp > 0:
        total = total * 10 + temp % 10
        temp //= 10
    return total == num

def is_prime(num):
    for x in range(2, int(num ** 0.5) + 1):
        if num % x == 0:
            return False
        return True if num != 1 else False

if __name__ == '__main__':
    num = int(input('请输入你想判断的数字: '))
    if is_palindrome(num) and is_prime(num):
        print('是的,它是一个回文素数')

变量的作用域

def foo():
    b = 'hello'

    # python中可以在函数内部再定义函数
    def bar():
        c = True
        print(a)
        print(b)
        print(c)

    bar()
    # print(c) # NameError: name 'c' is not defined

if __name__ == '__main__':
    a = 100
    # print(b) $ NameError: name 'b' is not defined
    foo()

输出:

100
hello
True

我们在上面代码的if分支中定义了一个变量a,这是一个全局变量(global variable),属于全局作用域,因为它没有定义在任何一个函数中,在上面的foo函数中我们定义了变量b,这是一个定义在函数中的局部变量(local varible),属于局部作用域,在foo函数的外部并不能访问到它;但对于foo函数内部的bar函数来说,变量b属于嵌套作用域,在bar函数中我们是可以访问到它的。bar函数中的变量c属于局部作用域,在bar函数之外是无法访问的。事实上,python查找一个变量时会按照“局部作用域”“嵌套作用域”“全局作用域”和“内置作用域”的顺序进行搜索,我们之前使用的 input、print、int 等都属内置作用域

从现在开始可以按照如下格式进行书写

def main():
	# Todo: Add your code here
	pass

if __name__ == '__main__':
	main

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

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

相关文章

企业级信息系统开发学习笔记05 初探Spring AOP

文章目录 一、学习目标二、Spring AOP(一)AOP基本含义(二)AOP基本作用(三)AOP和OOP对比(四)AOP使用方式(五)AOP基本概念 三、采用配置方法使用AOP&#xff08…

STM32实验-高级定时器输出指定个数PWM

STM32F103ZET6中有TIM1,TIM8两个高级定时器,每一定时器都有 1、一个16位向上、向下、向上/下自动装载计数器 2、一个16位预分频器和四个独立从输入输出通道 3、每一个通道都可用于输入捕获、输出比较、PWM和单脉冲模式(除了基本定时器,高级定…

Cesium-源码修改-gltf增加纹理贴图改变3dtiles外观

一、需求 Cesium支持加载gltf和3dtiles等三维数据模型,实现了很好的封装,往往只需要给一个uri就能加载模型文件,并实现贴图渲染等。但是好的封装带来的问题是如果开发者想要自定义贴图,那该怎么办?不得不从源码入手。 …

条码控件Aspose.BarCode入门教程(6):如何在C# 中生成GS1-128 条码

Aspose.BarCode for .NET 是一个功能强大的API,可以从任意角度生成和识别多种图像类型的一维和二维条形码。开发人员可以轻松添加条形码生成和识别功能,以及在.NET应用程序中将生成的条形码导出为高质量的图像格式。 Aspose API支持流行文件格式处理&am…

三、Golang环境搭建及打包和工具链

一、环境搭建 从https://golang.google.cn/dl/下载安装即可 新建GO_HOME 系统环境变量,指向go的安装目录 在终端输入go dev即可测试有无安装成功 二、包 所有Go程序的程序都会组织成若干组文件,每组文件被称为一个包。每个包的代码都可以作为很小的复用…

webpack 5 实战(1)

一、为什么使用webpack 个人将前端开发分为三个阶段: 1.1 Web1.0 Web1.0前端主要工作: 前端主要编写静态页面对于JavaScript的使用,主要是进行表单验证和动画效果制作 1.2 Web2.0之AJAX 伴随着AJAX的诞生,前端的工作模式也发…

什么牌子的蓝牙耳机音质最好?盘点2023音质最好的蓝牙耳机

近几年,蓝牙耳机在日常生活中的出现频率越来越高,不管是运动、听歌、追剧、玩游戏等等都能看到蓝牙耳机的身影。接下来,我来给大家盘点几款音质好的蓝牙耳机,感兴趣的朋友可以了解一下。 一、南卡小音舱Lite2蓝牙耳机 参考价&…

使用 WSL 在 Windows 上安装 Linux提示无法解析服务器的名称或地址及0x80370114问题解决

开发人员可以通过WSL在windows电脑上安装Linux发行版,并可以直接在电脑上使用Linux应用程序、实用程序和Bash命令行工具等。 先决条件 必须运行 Windows 10 版本 2004 及更高版本(内部版本 19041 及更高版本)或 Windows 11 才能使用以下命令…

结合企业实践来规范你的Git commit(含插件使用指南)

🏆 文章目标:了解通用的Git commit规范,并在企业的团队内部进行实践。 🍀 如何规范你的Git commit(理论结合企业的实践) ✅ 创作者:Jay… 🎉 个人主页:Jay的个人主页 &am…

论文学习——数据挖掘技术在水文数据分析中的应用

文章目录0 引言1 数据挖掘技术及工具1.1 什么是数据挖掘?1.2 数据挖掘的过程?1.3 常用的数据挖掘技术1.4 ODM2 水文数据分析系统功能设计3 系统实现与应用3.1 数据获取与清理3.2 模型建立4 结语2012年12月 计算机工程与设计 0 引言 洪水是现实生活中频发…

数据结构_第十三关(3):归并排序

目录 归并排序 1.基本思想: 2.原理图: 1)分解合并 2)数组比较和归并方法: 3.代码实现(递归方式): 归并排序的非递归方式 原理: 情况1: 情况2&#…

《剑指大前端全栈工程师》--大前端时代全站式开发,直指大厂P7技术专家

【内容提要】 实力打造大前端时代,走在时代的钱端!   实战驱动教学,探索前端黑科技。紧跟企业实际技术选型,追求技术的实用性与前瞻性完美结合!   本书对大前端技术栈进行了全面的讲解,内容涉及HTML5CS…

AI产品铺天盖地,企业却用不上?

近年来,随着人工智能技术的飞速发展,越来越多的企业开始关注并尝试使用人工智能技术来提高业务效率和降低成本。然而,国内企业使用人工智能技术仍然存在一些困难和问题,主要原因如下: 国外产品不稳定或不安全 目前国内市场上存在许多国外的AI产品,例如ChatGPT、GPT-4等,但这些…

QT CTK控件 CTK开发(二)

CTK 为支持生物医学图像计算的公共开发包,其全称为 Common Toolkit。为医学成像提供一组统一的基本功能;促进代码和数据的交互及结合;避免重复开发;在工具包(医学成像)范围内不断扩展到新任务,而不会增加现有任务的负担;整合并适应成功的解决方案。 本专栏文章较为全面…

教你如何搭建物业-后勤管理系统,demo可分享

1、简介 1.1、案例简介 本文将介绍,如何搭建物业-后勤管理。 1.2、应用场景 该应用包含疫情上报、绿化、安保等管理功能。 2、设置方法 2.1、表单搭建 1)新建表单【返区登记】,字段设置如下: 名称类型名称类型姓名单行文本…

【历史上的今天】3 月 17 日:苹果起诉微软;CN 域名开放注册;赛博朋克之父出生

整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来。 今天是 2023 年 3 月 17 日,在 1958 年的今天,我国第一台黑白电视机诞生。当时,我国电视机研制技术与日本基本处在同一起跑线,是…

四十六、docker-compose部署

一个项目肯定包含多个容器,每个容器都手动单独部署肯定费时费力。docker-compose可以通过脚本来批量构建镜像和启动容器,快速的部署项目。 使用docker-compose部署主要是编写docker-compose.yml脚本。 一、项目结构 不论是Dockerfile还是docker-compo…

如果你想从事人工智能职业,学习Python吧

人工智能并不会抢走你的工作,至少目前还不会。人工智能和机器学习(AI/ML)最好的应用是补充人类的创造力,而不是取代它。具有讽刺意味的是,最好的大型语言模型(LLMs)可能是通过使用受版权保护的人…

本地环境配置自签名HTTPS证书

在本地使用的线上的https证书的话,每三个月需要更新一次比较繁琐,用本地证书也可以满足调试需求也会方便许多 下载签名工具: https://github.com/FiloSottile/mkcert/releases/tag/v1.4.4 根据需求下载对应系统的版本,以64位的win…

有奖征文|小鱼再进化!OceanBase 4.1免费体验

OceanBase 4.0(小鱼)的首次亮相是在 2022 年 8 月,作为业内首个单机分布式一体化架构的数据库,4.0 版本兼顾了分布式架构的扩展性和集中式架构的性能优势,在同等硬件条件下实现单机性能赶超集中式数据库的同时&#xf…