欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Python学习之函数

程序员文章站 2022-03-26 10:52:21
理解函数 高中数学中,学习的函数 有一次函数,二次函数,高次函数,正余弦函数,正余切函数、指数函数、幂函数等等,都是函数。从这一节开始,学习程序中的函数。 f(x) = ax...
理解函数

高中数学中,学习的函数 有一次函数,二次函数,高次函数,正余弦函数,正余切函数、指数函数、幂函数等等,都是函数。从这一节开始,学习程序中的函数。

f(x) = ax + b
其中a、 b是常数,x是变量,f(x)随x的变化而变化。那么x就叫做函数的自变量,而f(x)叫做函数的因变量。
假如x = 2,那么上面的函数式可以写为f(x) = a * 2 + b
这样就不难理解程序中的函数了。
由于函数本身是一个表达式,这个表达式会根据自变量x的变化而得到不同的结果。所以,程序中,编写的函数也是为了根据参数方便被重复调用。
可以把x当作程序中的参数来理解。
和数学中函数不同的是,程序中的函数的参数并不是一个数,它可以是任何对象。

对于变量的理解

在程序中,变量不仅仅指的是一个具体的数字,也可以是任何对象。
再来拿一个列子,比如f(x) = 2 * x + 3,
那么在这个一次函数中,如果x=2 那么,f(x)= 2 * 2 + 3
结果为7,我们便称这是一个映射。
所以X可以是任何对象,只是我们在数学中习惯了将它作为一个数字。
可以这样理解,X就是一个占位符,因为我们不知道函数具体想要实现什么,那么这个位置暂且先用x来代替,让其占着这个位置,等待交互模式下的输入。
所以,程序中的变量说过来要比我们中学时期学过的函数要复杂的多。
关于变量的命名,Python中一般使用小写字母来作为变量的开头,也可以是下划线,以表示区别。

建立一个简单的函数
>>> x = 3
>>> y = 2 * x + 3
>>> y
9
>>> 

上面这个函数和中学学习的数学没有任何区别,当然,在这就也没有什么实际的意义了,只是引出来作为理解函数中的变量。

思考,如果我们这次让x = 4 那么y的值将会是多少?

>>> x = 3
>>> y = 2 * x + 3
>>> y
9
>>> x = 4
>>> y
9
>>> 

发现,y的结果依然没有变,为什么呢?
原因是这样的,我们在前面提到过变量,在Python中,变量无类型,对象有类型,我们只是将3 这个对象贴上了变量x的标签。经过第一次计算,y引用的依然是x = 3这个变量计算后的标签8,所以,我们只有再进行一个计算,这个结果就会跟着变化了。

>>> x = 3
>>> y = 2 * x + 3
>>> y
9
>>> x = 4
>>> y
9
>>> y = 2 * x + 3
>>> y
11
>>> 

有没有发现,上面的函数在引用变量的时候,都是对变量进行先定义,然后再使用的,如果不预先定义,直接使用函数进行引用会发生什么错误呢?
来看看:

>>> y = 2 * a + 3
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'a' is not defined
>>> 

上面的变量a是没有预先定义的,所以,当直接用函数引用变量的时候出错了。而且错误很明确,a 没有被定义。
所以,无论是python还是java还是类C,对变量都是坚持先声明,后使用的规则。记住这是规则。
在java中是这样。

public class test{
    public static void main(String args[]){
        int c = a + 2;
        System.out.println(c);
    }
}
#然后再cmd命令窗口执行
D:\ProjectFiles\JavaFiles>javac test.java
test.java:3: 错误: 找不到符号
                int c = a + 2;
                        ^
  符号:   变量 a
  位置: 类 test
1 个错误

提示说找不到符号a ,那么我们看代码发现,并没有定义变量a,然后我们定义一个变量a再进行运行程序

public class test{
    public static void main(String args[]){
        int a = 3;
        int c = a + 2;
        System.out.println(c);
    }
}
#然后再cmd命令窗口执行:
D:\ProjectFiles\JavaFiles>javac test.java     #编译通过

D:\ProjectFiles\JavaFiles>java test
5

D:\ProjectFiles\JavaFiles>

java中的具体编译结果,我在这里就不解释了。
C语言中是这样的。
如果变量a未被定义:

#include 
void main(int){
    int c = a + 3;
    printf("%d", c);
}
错误  1   error C2065: “a”: 未声明的标识符   d:\projectfiles\cfiles\consoleapplication1\consoleapplication1\源.cpp    3   1   ConsoleApplication1
    2   IntelliSense:  未定义标识符 "a"   d:\ProjectFiles\CFiles\ConsoleApplication1\ConsoleApplication1\源.cpp    3   10  ConsoleApplication1

如果a 被定义:

#include 
void main(int){
    int a = 3;
    int c = a + 3;
    printf("%d", c);
}

将会在cmd窗口显示一个结果6,
所以,再三声明,无论是哪种编程语言,变量必须是先声明,后使用。

建立实用的函数

上面写的简单函数只是为了引进来让理解函数和变量的关系。并没有什么实际的意义。所以,这次为了让函数“规范化”,写一个.py的文件。
需求,定义一个函数,要求这个函数有两个参数a,b,然后通过给函数传递参数,执行后并将结果输出到屏幕上。

[root@python Script]# cat ftest.py 
#!/usr/bin/env python
#coding:utf-8
def add(a,b):
    c = a + b
    print c

if __name__ == "__main__":
    add(3,8)
[root@python Script]# python ftest.py 
11
[root@python Script]# 

说明:
def add(a,b):这是声明一个名为add并且参数为a,b的函数。def也就是define定义的意思。
c = a + b :函数里面的表达式块,将a + b的结果赋值给c。
print c,将变量c 的结果输出到屏幕上。
if name == “main“:这个暂时不用理解它,就当作程序的入口就行,记下来就行。
add(3,8):这个是调用前面定义的函数add并且传入两个实参3、8。
很好理解吧。

注意Python中函数的命名规则
· 函数名以数字、字母和下划线组成
· def是Python中声明函数的关键词,也是define的简写。
· 函数名后面以一对圆括号结束,括号里面可以有参数列表,也可以无参数列表,有参数列表的时候,参数列表数量并没有限制
· 函数体当中的语句块也是以四个空格为缩进量。
练习:
减法函数:

>>> def sub(a,b):
...     c = a - b
...     print c
... 
>>> sub(4,1)
3
>>> 

乘法函数:

>>> def multiplication(a,b):
...     c = a * b
...     print c
... 
>>> multiplication(4,5)
20
>>> 

除法函数:

>>> def pision(a,b):
...     c = b / a
...     print c
... 
>>> pision(3,9)
3
>>> 

取余函数:

>>> def remainer(a,b):
...     c = a % b
...     return c
... 
>>> remainer(10,3)
1
>>> 

说明:以上引入的参数都是没有类型的,也一直提到变量无类型,只有对象才是有类型的。所以在定义函数的时候,函数里面的参数是不确定的,因为它可以引用任何对象类型。只要函数体里面的运算成立,变可以引用任何参数。如果函数体里面的运算不成立,则会报错。
示例

>>> def test(a,b):
...     return a + b
... 
>>> test("Python ","Java")
'Python Java'
>>> test("Python ",12345)
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 2, in test
TypeError: cannot concatenate 'str' and 'int' objects

第一次调用的时候,因为两个参数都是字符串,所以连接没有问题,但是第二个调用函数的时候,一个是字符串,一个是整型数值,所以返回的运算语句是不成立的,所以报错。不过可以在实参的传递中进行类型转换。

>>> test("Python ",str(12345))
'Python 12345'
>>> 

从实验的结果中发现,返回的a + b完全取决于传入参数的对象类型,而这种依赖关系被称作多态,因为Python也是一种面向对象的编程语言,所以,在这里引出面向对象的三大特性,继承、封装、多态。
注意,Python中,为对象编写接口,而不是为数据类型编写接口

命名

Python中,命名的一般要求:
文件: 全小写,也可以使用下划线
函数名: 小写,和下划线使用,提高程序的可读性,也可以采取驼峰命名。如:myEclipse
函数的参数: 如果一个函数的参数名称和保留的关键字冲突,可以使用一个后缀的下划线来区分
变量: 字母数字下划线。

函数的调用

调用函数的好处:

降低编程的难度 通常将一个复杂的问题分解为多个小的问题而解决,以减少编程的复杂程度。
代码重用 通常也会叫做开耦合,避免重复调用一段代码
示例函数的调用:

>>> def add(a,b):
...     print "a = ", a
...     print "b = ", b
...     c = a + b
...     print "c = ", c
... 
>>> add(1,2)
a =  1
b =  2
c =  3
>>> add(4,5)
a =  4
b =  5
c =  9
>>> 

注意,这样写一定要注意传递参数的次序,如果参数太多,次序记起来很麻烦,可以直接将参数的赋值写到调用函数的模块儿里面,像下面这样:

>>> add (a = 10,b = 4)
a =  10
b =  4
c =  14
>>> add(b = 3,a = 6)
a =  6
b =  3
c =  9
>>> 

也可以直接在定义函数的时候直接在参数列表中赋值,像下面这样:

>>> def add(a,b = 2):
...     print "a = ",a
...     print "b = ",b
...     c = a + b
...     print "c = ",c
... 
>>> add(3)
a =  3
b =  2
c =  5
>>> add(a = 4,b = 6)                #也可以重新赋值。
a =  4
b =  6
c =  10
>>> 
返回值

Python中的返回值有两种:
返回一个值
返回多个值
具体看一下文档:
return_stmt ::= “return” [expression_list]

return may only occur syntactically nested in a function
definition, not within a nested class definition.

If an expression list is present, it is evaluated, else None is
substituted.

return leaves the current function call with the expression list
(or None) as return value.

When return passes control out of a try statement with a
:
说明:”return”只能在语法上嵌套在定义的函数中,而不是被嵌套在定义的类中。
如果一个表达式列表是存在的,那么它将会被求值计算,否则将使用“None”替代
”return”离开当前函数调用的表达式并返回值。

上面说明中,类的定义在以后将会学习,这里只看第三个。
示例:

>>> def add(a,b):
...     c = a + b
...     return c
... 
>>> add(1,2)
3
>>> def sub(a,b):
...     c = a * b
...     return c , a, b
... 
>>> sub(3,9)
(27, 3, 9)
>>> 

第一次接触函数就暂时学习到这里