日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

python3中的函數與參數及空值問題_python

作者:AI_LX ? 更新時間: 2022-12-26 編程語言

畫星星

程序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。

原文鏈接:https://blog.csdn.net/AI_LX/article/details/128063324

欄目分類
最近更新