每日一课 | 详解抽象之函数

昨天

Python大本营每日一课

大家好,我是营长,上期营长分享了数据科学”的知识点:,不清楚的小伙伴可戳这👉每日一课 | 条件、循环及其它语句
本期营长将为大家分享如何快速入门Python开发。
这期分享营长邀请的是应书澜(深耕 Java 技术栈,在 Python、C 语言方面亦有丰富经验,擅长预测算法,分布式中间件)分享Python开发14天快速入门

抽奖之函数

DAY06

在实际应用中,通常以函数作为一个基本的代码单元,对一组需求进行抽象,用于完成一项具体的任务。函数能提高应用的模块性和代码的重复利用率。在前面的文章中,我们已经接触到了 Python 提供的一些内建函数,比如 print()、sqrt()、append()、pop()。除了 Python 提供的内建函数,我们也可以自己创建函数,这种函数被称为用户自定义函数。

函数的定义与调用
在 C/C++、Java 中,函数(方法)的定义形式如下:
修饰符1,修饰符2,…,返回值类型,函数名(参数列表)
public static String getPath(String basePath, String fileName)
Python 中函数的定义则“简洁”得多,Python 函数无需声明返回值类型,也无需修饰符,一般地,函数的定义形式如下:
函数定义符,函数名(参数列表)
def getPath(basePath, fileName):
def getName():
基于前一篇文章 Python 基础的知识储备,在此,直接以一个简单的比较函数 compare() 来举例介绍,下面的代码中定义了一个比较函数,并执行了3次调用。
#定义函数
def compare(parameter1, parameter2):
    if (parameter1 > parameter2):
        print(1)
    elif (parameter1 == parameter2):
        print(0)
    else:
        print(-1)

#调用函数
compare(123,456)
compare(3.14,1.5)
compare(12,12.1)

执行结果:
-1
1
-1
参数传递变量与引用在 Python 中,所有类型:函数、模块、数字、字符串、列表、元组、字典等等都是对象,而变量是没有类型的,怎么理解呢?请看如下实例:
a = 12
print("a=", a)
a = "ABCDE"
print("a=", a)
a = [1,2,3,4,5]
print("a=", a)
a = (1,2,3,4)
print("a=", a)
a = {'key':12,'key1':13}
print("a=", a)

执行结果:

a= 12a= ABCDEa= [1, 2, 3, 4, 5]a= (1, 2, 3, 4)a= {'key': 12, 'key1': 13}

从上面的例子可以看出,同一段代码中,同一个变量 a 先后被赋值整数、字符串、列表等多种类型,这是因为变量本身没有类型,它仅仅只是一个对象的引用(指针),它可以引用任何类型,上面例子中,变量 a 先后引用多种数据类型,本质上也仅仅是改变指向而已。

不可变类型。

上文提及,变量没有类型,仅仅作为对象的引用,我们可以在深化一下,如下例子:

a = 12a = 15

上述过程的实质就是:首先创建一个对象 12,让 a 指向它,然后再创建一个对象 15,再让 a 指向后者,而前者12就被丢弃。这个过程是通过创建新的对象来实现的,并不是直接改变 a 的值,一定要理解其中区别。

这种只能通过创建新的对象才能改变对变量的赋值的数据类型,称为不可变类型,如整数、字符串、元组都是不可变类型。再来看一个例子:

def change(x):
    x = 10

a = 5
change(a)
print("a=",a)

执行结果:

a= 5

调用 change() 函数并没有改变变量 a 的内容,这是因为,定义了一个变量 a,a 指向数字 5,然后执行 change 函数,是复制 a 到 x,刚开始 x 也指向数字5,在函数体内执行 x=10,由于整数是不可变对象,所以将创建一个新的对象 10,并将 10 赋值给 x 变量,此时 x 指向10,而 a 本身并没有发生改变,仍然指向5。

在 Python 中,对于不可变对象,调用自身的任意方法,并不会改变对象自身的内容,这些方法会创建新的对象并返回,保证了不可变对象本身是永远不可变的。

可变类型

与不可变类型相对就是可变类型,包括列表、字典、集合、队列等。如下例子:

def change(x):
    x.append(2012)

a = [1,2,3,4]
change(a)
print("a=",a)

执行结果:

a= [1, 2, 3, 4, 2012]

很明显,a 发生了改变,原因分析:执行 change() 方法时,x 指向列表 [1,2,3,4],因为列表是可变对象,执行 x.append(5) 时,并不会产生新的对象,而是直接作用在原来列表对象 [1,2,3,4]上,进而列表对象改变为 [1,2,3,4,5]

函数的参数类型

Python 中,函数的参数有四种类型:必须参数、关键字参数、默认参数和不定长参数。

必须参数

函数在定义的时候,已经声明了参数的数量,我们在调用函数的时候,参数的数量必须与声明时一致,且要注意顺序。

实例1:参数数量要对应。

#声明参数为一个def update(arg):    arg = arg + 1

#正确update(12)#不正确,参数缺失update()#不正确,参数多余update(1,2)

实例2:参数顺序要一致。

def printInfo(name, sex, age):    print("name:",name)    print("sex:",sex)    print("age:",age)

#正确printInfo("Jack","female", 18)#错误,参数顺序不对应printInfo(18,"Jack","female")

关键字参数

上面已经提到,调用函数时,不仅参数数量要相等,还要顺序匹配。在 Python 中,还有一种方式可以更灵活的匹配参数:函数调用使用关键字参数来确定传入的参数值。

如下实例

def printInfo(name, sex, age):    print("name:",name)    print("sex:",sex)    print("age:",age)

#都是正确的printInfo(name="Jack",sex="female",age=18)printInfo(sex="female",name="Jack",age=18)printInfo(sex="female",age=18,name="Jack")

默认参数

有些场景下,如果调用函数时,参数错误可能会导致不可预期的严重后果,因此,为了增强函数的适应性和容错性,可以采取一种策略:调用函数时,如果没有传递参数,则会使用默认参数。如下实例:

#声明参数为一个def printInfo(name, sex, age=0):    print("name:",name)    print("sex:",sex)    print("age:",age)

#正确printInfo(name="Jack",sex="female")

不定长参数

有些场景下,我们希望设计一个参数数量不确定的函数,如任意个整数求和,调用形式可以是:sum(a)、sum(a,b,c)、sum(a,b,c,d)……,这时候我们需要使用一种不定长参数,一般定义形式如下:

def functionname([formal_args,] *var_args_tuple ):
    functionbody

加了(*)的变量名会存放所有未命名的变量参数。如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。如下实例:

#定义一个求和函数
def sum(num, *num_list):
    sum = num
    for element in num_list:
        sum += element
    print("sum=",sum)
    
sum(1)
sum(1,2,3,4)

执行结果:

sum= 1
sum= 10

Return 语句

return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的 return 语句返回 None,表示没有任何值。如果函数没有显式的使用 return 语句,Python 函数也会默认返回 None 对象。

#定义比较函数
def compare(parameter1, parameter2):
    if (parameter1 > parameter2):
        return 1
    elif (parameter1 == parameter2):
        return 0
    else:
        return -1
    
result = compare(123,456)
print("result=",result)

执行结果:

result= -1

变量作用域

在前面章节的学习中,读者应该注意到一个问题,变量的使用非常多,有些地方甚至同名,那么,它们会不会冲突呢?实例如下:

#这里的 a 是全局变量
a = 123
def function():
    a = 10 #这里的 a 是局部变量
    print("I a=",a)

function()
print("II a=",a)

执行结果:

I a= 10
II a= 123

上述实例可见,同名的变量并没有发生冲突,这是因为它们的“作用域”不同,变量只在自己的作用域内有效,a=123 处属于全局变量,function() 函数内部 a=10 属于局部变量,作用域不同,因此并不会冲突。

作用域分类

按作用域不同,变量可分为四种类型:L(Local),局部作用域;E(Enclosing),闭包函数外的函数中;G(Global),全局作用域;B(Built-in),内建作用域;

使用变量时,会根据作用域进行查找,优先级顺序为:L –> E –> G –>B,即在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。关于变量作用域的更多内容可查看博文《Python 变量作用域》。

(0)

相关推荐

  • Python 中的函数装饰器和闭包

    函数装饰器可以被用于增强方法的某些行为,如果想自己实现装饰器,则必须了解闭包的概念. 装饰器的基本概念 装饰器是一个可调用对象,它的参数是另一个函数,称为被装饰函数.装饰器可以修改这个函数再将其返回, ...

  • Python之函数的定义与使用示例

    Python之函数的定义与使用示例,结合实例形式分析了Python函数的定义.参数.变量作用域.返回值等相关概念与使用技巧. Python定义函数使用def关键字,一般格式如下: def 函数名(参数 ...

  • 每日一课 | 详解Python的两大特性

    原创 zglg .Alicia Python大本营 昨天 01 大家好,我是营长,Python大本营新一期的专栏又开始了,上期营长分享了机器学习,详情可戳"被疯转的机器学习资料,究竟有什么特 ...

  • 天王星换座之前充满巨变的一周,12星座每日运势详解

    5月 第2周 眼花缭乱的星象,精彩的一周来了! 赶紧盘点每日星象,看看如何把握好运 LEARN MORE 水星刑冥王星 5.7 捣乱指数:★★★★ 周一星象并不好,水星冥王刑克会让我们在思想上.情绪上 ...

  • 文王六十四卦金钱课详解

    六十四卦排列顺序与读音 按周易古经顺序排列 1.乾卦:读 qián 2.坤卦:读 kūn 3.水雷屯卦:读 zhūn 4.山水蒙卦:读 méng 5.水天需卦:读 xū 6.天水讼卦:读 sòng 7 ...

  • 六十四卦金钱课详解

    一 占卦者净手诚心,用铜钱或硬币六枚放在手中,两手高举过头三摇或六摇,自上而下自然放置排成一行,按卦象便知吉凶祸福.占卜者连摇三卦,可知事物发展规律的定向之所在.兴衰与成败,也可使未来行知,事后无悔, ...

  • 《巧连神数》215课详解之五:第六十一~第八十课 | 原梓番博客

    第六十一课 方离发福生才地,又入堆金积玉门. 解释:刚离开了好运发财的地方,又进到了金玉满堂的大门之内,富贵伴随之象.但除富贵之外,并为提及人生的其他方面,如事业.健康等. 第六十二课 须放开肚皮吃饭 ...

  • 《巧连神数》215课详解之七:第101~第120课 | 原梓番博客

    第一百零一课 知足方能图快乐,吃亏纔(才)是发财源. 解释:此课表的含义和'知足常乐,吃亏是福.'几乎没有任何差异.此课表是劝当事人切莫计较一些看似吃亏的交易或事件,这是发财的根源. 第一百零二课 苦 ...

  • 【视频】Excel函数每日一讲(47):详解roundup、rounddown函数算停车收费

    以上视频的所有教学内容,选自教材<玩转Office轻松过二级>(第3版) 书上包含所有方法.技巧.题目,可以自己看书自学. 字都认识,为啥要让别人念呢? 选自本书第9章前言 公式和函数,E ...

  • 书法二期预热课-笔法详解

    书法二期预热课-笔法详解

  • VLOOKUP函数从入门到精通,15种用法详解。

    VLOOKUP函数从入门到精通,15种用法详解。