python3中的函数与参数及空值问题

目录
  • 画星星
  • 空值None
  • 函数与Lambda
    • 一、函数定义
    • 二、引用变量查找
    • 三、传值调用函数
    • 四、函数对象
    • 五、函数文档
  • 旋转角度
  • 绘制函数图形

画星星

程序2-7-7主要使用turtle.forward前进操作和turtle.left左转操作在屏幕上画星星。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#2-7-8.py
import turtle
turtle.color('Green','yellow')
while True:
    turtle.forward(200)
    turtle.left(150)
    print(turtle.pos())
    if abs(turtle.pos()) < 1:
        break
print('按回车键退出')
input()

程序2-7-7.py运行结果如下:

同时,程序2-7-7.py还输出了如下所示的线转角处(绘制一条直线后转角绘制另一个直线,2条直线的交点)的位置信息:
(200.00,0.00)
(26.79,100.00)
(126.79,-73.21)
(126.79,126.79)
(26.79,-46.41)
(200.00,53.59)
(0.00,53.59)
(173.21,-46.41)
(73.21,126.79)
(73.21,-73.21)
(173.21,100.00)
(0.00,-0.00)
按回车键退出
现对程序2-7-7.py分析如下:
1、该程序使用了以下几个函数:
(1)forward函数前进200,用于绘制直线。
(2)left函数左转150度,用于转角,绘制另一条直线。
(3)turtle.pos()返回当前位置坐标 (x,y) (坐标为 Vec2D 矢量类对象)。
(4) abs函数返回一个数的绝对值。 参数可以是整数、浮点数或任何实现了 abs() 的对象,当参数是一个复数时,返回它的模。在该程序中, abs的作用如下:
使用pos返回一个当前坐标后,abs求该Vec2D坐标到原点的距离(从原点出发的向量长度)。矢量空间内的所有矢量赋予非零的正长度或大小,在二维的欧氏几何空间 R中定义欧氏范数,在该矢量空间中,元素被画成一个从原点出发的带有箭头的有向线段,每一个矢量的有向线段(向量)的长度即为该矢量的欧氏范数。
由于Vec2D是一个二维矢量类,用来作为实现海龟绘图的辅助类,也可以在海龟绘图程序中使用,它派生自元组,因此矢量也属于元组。Vec2D主要提供以下运算 (a, b 为矢量, k 为数值):
a + b 矢量加法
a - b 矢量减法
a * b 内积
k * a 和 a * k 与标量相乘
此外,Vec2D类还实现了 abs操作,如下面代码片断所示(摘自Vec2D类源代码)。

class Vec2D(tuple):
  ...
    def __abs__(self):
        return (self[0]**2 + self[1]**2)**0.5

2、程序2-7-7.py的执行过程如下:
(1)通过turtle.color(‘Green’,‘yellow’)函数设置颜色为绿色画笔、黄色填充。
(2)创建循环体,循环体内容为:
首先,将海龟定位于原点。
然后,turtle.forward(200)前进200步,turtle.left(150)左转150度,print(turtle.pos())打印出当前海龟位置。
最后,通过abs(turtle.pos())判断当前向量(从原点到当前海龟位置的向量)的长度,如果长度<1,说明当前位置已经回到了起点(原点),就退出循环。如果长度>=1,则继续循环。

空值None

Python None 对象,表示缺乏值、空值。
下面代码定义了x和y共2个变量,其中,x初始化值为0,而y设为了空值,x虽然为0,但仍然属于有值状态,而y属于空值状态。

>>>x=0
>>>y=None
>>>x==None
False
>>>y==None
True

函数与Lambda

一、函数定义

Python定义函数使用关键字 def,后跟函数名与括号内的形参列表。函数语句从下一行开始,并且必须缩进。
程序2-7-10-1.py定义了函数getSum,完成参数求和后返回 。
#!/usr/bin/env python3

# -*- coding: utf-8 -*-
#2-7-10-1.py
def getSum(x1,x2,x3,x4):
    y=x1+x2+x3+x4
    return y

print(getSum(11,22,33,44))
程序2-7-10-1.py执行结果如下:

110

程序2-7-10-1.py执行过程如下:
1、定义函数getSum,使用def关键字+函数名getSum的方式进行定义,参数为括号内的4个变量x1、x2、x3、x4。
函数的执行体为函数定义的下一行,共2行。
(1)第1行y=x1+x2+x3+x4,将4个参数之和赋值给变量y。其中,y是函数内局部变量,而x1、x2、x3、x4为函数局部变量。
(2)第2行return y,将y返回,return语句功能是是函数返回值,没有 return 语句的函数也返回值,只不过这个值是 None。
2、调用getSum函数,并打印函数返回结果。

二、引用变量查找

函数在执行时使用函数局部变量符号表,所有函数变量赋值都存在局部符号表中;引用变量时,其查找顺序为:首先,在局部符号表里查找变量,然后,是外层函数局部符号表,接着是全局符号表,最后是内置名称符号表。因此,虽然可以引用全局变量和外层函数的变量,但是最好不要在函数内直接赋值(除非是 global 语句定义的全局变量,或 nonlocal 语句定义的外层函数变量)。
程序2-7-10-2.py定义了函数getSum,完成参数求和后返回,与2-7-10-1.py基本相同,不同之处在于,在getSum函数体内出现了变量y,而在getSum函数体外也出现了变量y。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#2-7-10-2.py
y=9
def getSum(x1,x2,x3,x4):
    y=x1+x2+x3+x4
    return y

print(y)
print(getSum(11,22,33,44))
print(y)

程序2-7-10-2.py的执行结果为:

9
110
9

观察程序2-7-10-2.py的执行结果,可发现,虽然,在getSum函数定义之前(之外),已经定义了变量y=9,随后又在getSum函数体内将变量y的值改为了4个参数之和110,那么在执行完getSum函数后,y的值会变为110,但在此处却仍没有变化,还是9。这是什么原因呢?答案是:getSum函数体内的y存在于函数局部变量符号表内,而getSum函数定义之外的y属于全局变量,2个y不属于同一变量,因此,对getSum函数体内的y值进行的修改并不影响函数体之外定义的y的值。
那么,如果一定要在getSum函数体内对函数体外定义的y进行修改,可按程序2-7-10-3.py所示的方法进行。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#2-7-10-3.py
y=9
def getSum(x1,x2,x3,x4):
     global y
     y=x1+x2+x3+x4
     return y
print(y)
print(getSum(11,22,33,44))
print(y)

程序2-7-10-3.py的执行结果为:

9
110
110

程序2-7-10-3.py与程序2-7-10-2.py基本一样,只是在函数体内通过global y,将y声明为全局变量,表示在函数体内使用的y就是全局变量y,并非函数体局部变量。
除了global还有一个语句nonlocal。nonlocal 语句会使得所列出的名称指向之前在最近的包含作用域中绑定的除全局变量以外的变量。 这种功能很重要,因为绑定的默认行为是先搜索局部命名空间。 这个语句允许被封装的代码重新绑定局部作用域以外且非全局(模块)作用域当中的变量。
与 global 语句中列出的名称不同,nonlocal 语句中列出的名称必须指向之前存在于包含作用域之中的绑定。程序2-7-10-4.py演示了nonlocal的用法。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#2-7-10-4.py
def printY():
     y=9
     print(y)
     def getSum(x1,x2,x3,x4):
          nonlocal y
          y=x1+x2+x3+x4
     getSum(100,2,3,4)
     print(y)

printY()

程序2-7-10-4.py的执行结果为:

9
109

对程序2-7-10-4.py分析如下:
1、该程序有2个函数体,这2个函数体是嵌套关系,即:getSum嵌套在printY内部。
2、对于getSum函数来说,在printY函数内部定义的y属于局部作用域以外且非全局(模块)作用域当中的变量,且属于最近的包含作用域(getSum包含在printY作用域内)中,getSum函数想访问printY函数的变量,需要声明该变量为nonlocal变量。
3、在getSum函数体内对printY函数体定义的y值的修改是有效的。因此,程序执行后,第一次打印出y的值为初始值9,第二次修改后再打印出y的值为修改后的值109。

三、传值调用函数

在调用函数时Python会将实际参数(实参)引入到被调用函数的局部符号表中,因此,函数参数都是使用按值调用来传递的,所谓按值传递,会将值进行复制生成函数的局部变量。当一个函数调用另外一个函数时,会为该调用创建一个新的局部符号表。
但是,有一点要特别注意,Python中的对象分为可变对象与不可变对象,比如整数288属于不可变对象,而列表[288,11]、[288,]就属于可变对象。具体来说,strings、tuples和numbers是不可变对象,而list、dict等则是可变对象。
对于不可变对象的按值传递就是直接复制其值,而可变对象的按值传递是复制其引用,因为可变对象的值在Python内部实质表现为一个指向该对象的引用(内存地址,可理解为指针),顺着这个引用才可在内存中找到该对象真正的值。程序2-7-10-5.py演示了参数传递的用法。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#2-7-10-5.py

def swapNum(x,y):
    temp=x
    x=y
    y=temp
def swapNums(nums):
    temp=nums[0]
    nums[0]=nums[1]
    nums[1]=temp

x=11
y=22

swapNum(x,y)
print(x,y)
n=[11,22]
swapNums(n)
print(n)

程序2-7-10-5.py的执行结果如下:

11 22
[22, 11]

对程序2-7-10-5.py分析如下:
1、该程序定义了2个函数swapNum和swapNums。
(1)swapNum函数想完成的功能是将传入的2个参数值进行修改,完成互换,要能完成对调用swapNum的函数实际参数进行修改,而不是对函数局部变量进行修改。
(2)swapNums函数想完成的功能是对传入的列表进行修改,将其第0个元素和第1个元素进行互换,并保证修改效果影响到调用swapNums函数的变量。
但是,虽然都是传值传递参数,但是swapNum函数的参数属于不可变变量,swapNum函数体会复制它的2个参数,形成属于自己的函数内部局部参数,实质已经与调用swapNum的函数参数无关,修改是无效的;而swapNums函数的参数是列表,属于可变变量,swapNums函数也会复制参数的值,但这个参数值是列表的地址(引用),那么传递到swapNums函数体内部的参数就是该列表的引用,对该引用的修改直接影响到调用swapNums的函数,修改是有效的。
2、该程序定义整型变量x和y后,将其作为参数传入swapNum,想完成x和y的互换, 这一操作是失败的,无法成功,然后该程序又定义了列表n,将其作为 参数传入swapNums,想完成第0个元素与第1个元素的互换,此操作是成功的。观察程序2-7-10-5.py的执行结果可验证这一结论。

四、函数对象

函数定义在当前符号表中把函数名与函数对象关联在一起。解释器把函数名指向的对象作为用户自定义函数。还可以使用其他名称指向同一个函数对象,并访问访该函数。程序2-7-10-6.py演示了函数对象的用法。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#2-7-10-6.py

def swapNums(nums):
    temp=nums[0]
    nums[0]=nums[1]
    nums[1]=temp

swap=swapNums
n=[11,22]
print(n)
swap(n)
print(n)

程序2-7-10-6.py的执行结果如下:

[11, 22]
[22, 11]

程序2-7-10-6.py首先定义了swapNums函数及其函数体内容;然后,定义一个变量swap,将swapNums函数赋值给变量swap(Python中的变量属于动态类型,对象的类型是可改变的),这样,swap成为了一个函数对象;最后,程序直接使用swap作为函数名调用swapNums函数。

五、函数文档

函数内的第一条语句可以是字符串,其意义在于:该字符串是DocString(文档字符串),利用文档字符串可以自动生成在线文档或打印版文档,还可以让开发者在浏览代码时直接查阅文档,Python 开发者最好可以养成在函数语句下一行中加入文档字符串的好习惯。程序2-7-10-7.py演示了函数文档的用法。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#2-7-10-7.py
def swapNums(nums):
    """
    swapNums函数接受一个列表对象,
    完成将列表对象的2个元素互换位置的功能。
    """
    temp=nums[0]
    nums[0]=nums[1]
    nums[1]=temp

print(swapNums.__doc__)
print("---------------------")
help(swapNums)

程序2-7-10-7.py的输出结果如下:
swapNums函数接受一个列表对象,
完成将列表对象的2个元素互换位置的功能。

Help on function swapNums in module main:

swapNums(nums)
swapNums函数接受一个列表对象,
完成将列表对象的2个元素互换位置的功能。

分析程序2-7-10-7.py,该程序的执行过程如下:
1、定义swapNums函数,函数功能为:互换列表的2个元素。
(1)在函数体的第1行(即:def定义语句的下一行)开始用三引号标注了一段字符串,该字符串(是DocString(文档字符串),用于说明函数功能和用法等事项。在Python中单引号和双引号都可以用来表示一个字符串,而三单引号和三双引号包围的字符串可保持原来的格式。
(2)函数体的第5行开始,是函数体的代码段,完成函数体的功能。
2、通过函数对象.doc(注意前后都是双_)属性,提取将DocString特性,该程序通过print(swapNums.doc)将函数swapNums的文档字符串打印在屏幕上。
3、通过help()调用提取DocString属性并打印在屏幕上。该程序通过help(swapNums)将函数swapNums的文档字符串打印在屏幕上。
2.2.2 Lambda

myfun1= lambda a,b:math.sqrt(pow(a,2)+pow(b,2))
myfun2=lambda x:1 if (x%2==0) else 0
print(myfun1(12,19))
print(myfun2(193))

旋转角度

程序2-7-11.py演示了以30度为步长逐渐增大角度进行旋转,从0度开始直到360度为止。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#2-7-11.py
import turtle
turtle.color('Green','yellow')
lineLine=50
for i in range(0,361,30):
    turtle.home()
    turtle.left(i)
    turtle.forward(lineLine+i)
    turtle.write(f"{i}>[{turtle.position()[0]},\n{turtle.position()[1]}]")
turtle.home()
turtle.color('Black','red')
turtle.write(f"[{turtle.position()[0]},\n{turtle.position()[1]}]") 

print('按回车键退出')
input()

程序2-7-11.py执行结果如下:

程序2-7-11.py的执行过程如下:
1、定义颜色为:画笔绿色,填充黄色,设定直线初始长度lineLine为50。
2、for循环绘制直线,i为旋转角度,从0度开始以30度为步长递增,直到360度结束,每递增一次就是一个循环。
(1)turtle.home()将位置和初始方向进行初始化,即:位置为(0.,0.),方向为0度。
(2)左转i度。
(3)forward绘制直线,每循环1次,直线长度递增30.
(4)在直线的一端(除开原点的另一个端),使用write绘制文本,文本内容为该直线端的位置。
3、循环结束,以黑色画笔(红色填充)绘制原点,并绘制原点坐标。

绘制函数图形

程序2-7-12.py演示了绘制一元二次函数的图像。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#2-7-12.py
import turtle

def getFunY(a,b,c,x):
    y=a*x*x+b*x+c
    return y

x=-10
a=0.6
b=0.2
c=0.8
while x<=10:
    turtle.up()
    turtle.goto(x,getFunY(a,b,c,x))
    turtle.dot(2)
    x+=0.1
input()

程序2-7-12.py的执行结果如下:

程序2-7-12.py的执行过程如下:
1、导入turtle库,为绘图做准备。
2、定义getFunY函数,接收参数a、b、c以及x,函数体的代码完成根据一元二次函数值的计算。
3、定义a、b、c、x值,其中x值初始化为-10
4、while循环,循环条件是x<=10。
(1)up函数抬起画笔
(2)goto函数移动到(x,y)处,其中x每次循环递增0.1,y为根据a、b、c、x值计算的getFunY函数的返回值。
(3)dot函数落笔画点。
x递增0.1,整个循环x的值从-10增加到10。

到此这篇关于python3-函数与参数以及空值的文章就介绍到这了,更多相关python3函数与参数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python3中函数参数传递方式实例详解

    本文实例讲述了Python3中函数参数传递方式.分享给大家供大家参考,具体如下: 之前在看北理工嵩天等老师的python3的课程,在第五周中老师讲到了函数的调用传递.老师讲了这样一个例子 #处理多个银行账户的余额信息 def addInterest(balances, rate): for i in range(len(balances)): balances[i] = balances[i] * (1+rate) def test(): amounts = [1000, 105, 3500,

  • python3中sorted函数里cmp参数改变详解

    今天在刷leetcode的时候,对于179题返回最大数,用python2中的sorted(cmp)会很方便,但是在python3中这一参数被取消了,经过查找,发现应该借助functools中的cmp_to_key函数,直接贴代码 import functools def cmp(a,b): if a > b : return -1 elif a < b : return 1 else: return 0 nums = [1,2,3,4,5,6] sorted_nums = sorted(num

  • python3中函数参数的四种简单用法

    下面给大家介绍python3中函数参数的四种简单用法,具体内容如下所示: def print_two(*args): arg1, arg2 = args print "arg1: %r, arg2: %r" % (arg1,arg2) def print_two_again(arg1, arg2): print "arg1: %r, arg2: %r" % (arg1, arg2) def print_one(arg1): print "arg1: %r&

  • Python3 main函数使用sys.argv传入多个参数的实现

    在运维过程中,有些时候需要向main函数中传递参数,以方便运维与测试,那么怎么向main函数中传入多个参数呢,下面以python3中的main函数为例,简单讲一下. 首先我们需要import sys,sys是python3的一个标准库,也就是一个官方的模块.封装了一些系统的信息和接口,然后再说说argv这个变量.「argv」是「argument variable」参数变量的简写形式,一般在命令行调用的时候由系统传递给程序.这个变量其实是一个List列表,argv[0] 一般是被调用的脚本文件名或

  • Python3.5基础之函数的定义与使用实例详解【参数、作用域、递归、重载等】

    本文实例讲述了Python3.5函数的定义与使用.分享给大家供大家参考,具体如下: 1.函数学习框架 2.函数的定义与格式 (1)定义 (2)函数调用 注:函数名称不能以数字开头,建议函数名称的开头用小写的字母 (3)函数有四种格式,分别是:无参数无返回值,有参数无返回值.无参数有返回值.有参数有返回值 #!/usr/bin/env python # -*- coding:utf-8 -*- # Author:ZhengzhengLiu # 无参数无返回值 def hello(): # 函数体/

  • python3中的函数与参数及空值问题

    目录 画星星 空值None 函数与Lambda 一.函数定义 二.引用变量查找 三.传值调用函数 四.函数对象 五.函数文档 旋转角度 绘制函数图形 画星星 程序2-7-7主要使用turtle.forward前进操作和turtle.left左转操作在屏幕上画星星. #!/usr/bin/env python3 # -*- coding: utf-8 -*- #2-7-8.py import turtle turtle.color('Green','yellow') while True: tur

  • Python3 中sorted() 函数的用法

    描述 sorted() 函数对所有可迭代的对象进行排序操作. 语法 sorted(iterable, key=None, reverse=False) iterable – 可迭代对象. key – 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序. reverse – 排序规则,reverse = True 降序 , reverse = False 升序(默认). 案例 >>> a_dict={'A':2,'B':3,

  • 浅谈Python3中print函数的换行

    Python3中print函数的换行 最近看了看Python的应用,从入门级的九九乘法表开始,结果发现Python3.x和Python2.x真的是有太大的不同之处,就比如这里的换行处理,怕忘记先记下来,好了,咱移步下文-- Python2.X中的代码: #!/usr/bin/env python #-*- coding: utf-8 -*- __author__ = '****' class PrintTable(object): '''打印九九乘法表''' def __init__(self)

  • python3中apply函数和lambda函数的使用详解

    目录 lambda函数 lambda是什么 lambda用法详解 lambda+map lambda+ filter lambda+ reduce 避免过度使用lambda 适合lambda的场景 总结 apply函数 lambda函数 lambda是什么 大家好,今天给大家带来的是有关于Python里面的lambda表达式详细解析.lambda在Python里面的用处很广,但说实话,我个人认为有关于lambda的讨论不是如何使用的问题,而是该不该用的问题.接下来还是通过大量实例和大家分享我的学

  • python3中rank函数的用法

    网上存在这么一个例子 obj = pd.Series([7,-5,7,4,2,0,4]) obj.rank() 输出为: 0 6.5 1 1.0 2 6.5 3 4.5 4 3.0 5 2.0 6 4.5 dtype: float64 之前一直没弄懂是啥意思 这里解释下 rank 表示在这个数在原来的向量中排第几名,有相同的数,按最小排序,取平均(默认).这里解释下 0 6.5 这里的0就是值得obj中的第一个数 也就是7 应该排名第七 但是第六名和第七名都一样 取平均值 1 1.0 这里的1指

  • python3中numpy函数tile的用法详解

    tile函数位于python模块 numpy.lib.shape_base中,他的功能是重复某个数组.比如tile(A,n),功能是将数组A重复n次,构成一个新的数组,我们还是使用具体的例子来说明问题:(至于为什么是在numpy.lib.shape_base中,我还是不太清楚.) 其实tile就是重复的意思,把一个数组a,当做模板,重复几次,生成另一个数组b 至于矩阵可以不以这样,还没有试过. 例子: 创建一个a,使用tile来创建b from numpy import * a=[0,1,2]

  • Keras中 ImageDataGenerator函数的参数用法

    一.Keras ImageDataGenerator参数 from keras.preprocessing.image import ImageDataGenerator keras.preprocessing.image.ImageDataGenerator(featurewise_center=False, samplewise_center=False, featurewise_std_normalization = False, samplewise_std_normalization

  • 关于python中readlines函数的参数hint的相关知识总结

    readlines的帮助信息 >>> fr=open('readme.txt') >>> help(fr.readlines) Help on built-in function readlines: readlines(hint=-1, /) method of _io.TextIOWrapper instance Return a list of lines from the stream. hint can be specified to control the

  • Vue3中SetUp函数的参数props、context详解

    1.setUp函数的第1个参数props setup(props,context){} 第一个参数props: props是一个对象,包含父组件传递给子组件的所有数据. 在子组件中使用props进行接收. 包含配置声明并传入的所有的属性的对象 也就是说:如果你想通过props的方式输出父组件传递给子组件的值. 你需要使用props进行接收配置.即props:{......} 如果你未通过Props进行接受配置,则输出的值是undefined <template> <div class=&

随机推荐