【循序漸進學Python】6.Python中的函數

1. 創建函數

一個函數代表一個行為并且返回一個結果(包括None),在Python中使用def關鍵字來定義一個函數,如下:

def hello(name):print 'hello,' + name + '!'

?接下來調用函數,并查看其返回值:

# output:
# hello,gy!
# None
print hello('gy')

可以看到hello函數首先打印了:Hello,gy!,然后我們又將其返回值也打印出來,在這里因為沒有返回具體的值,所以返回了None

?

下面我們可以定義一個用于計算斐波那契數列的函數,接收計算的位數(參數),返回計算的結果(返回值),如下:

1 def fibs(num):
2     result = [0,1]
3     for i in range(num - 2):
4         result.append(result[-2] + result[-1])
5     return result
6 
7 # output: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
8 print fibs(10)

?

2. 文檔字符串

文檔字符串指的是在函數開頭寫下該函數的說明字符串,該字符串會作為函數的一部分進行存儲。可以通過調用__doc__屬性來查看:

1 def fibs(num):
2     "根據指位數來計算斐波那契數列"
3     result = [0,1]
4     for i in range(num - 2):
5         result.append(result[-2] + result[-1])
6     return result
7 
8 # 輸出:根據指位數來計算斐波那契數列
9 print fibs.__doc__

?

3. 參數

函數使用參數來傳遞信息,而參數類型又基本分為兩大類型:可變類型參考和不可變類型參數。

?

3.1 不可變類型參數

不可變類型(字符串、數字和元組等)是不可變的,即無法修改,只能使用新的值來覆蓋。使用不可變類型作為函數的參數時:在函數內為參數賦值不會改變其外部變量的值,如下:

 1 # 字符串是不可變的
 2 def try_to_change(n):
 3     n = 'Gumby'
 4 
 5 name = 'Sunshine'
 6 
 7 # 嘗試改變參數的值
 8 try_to_change(name)
 9 
10 # output: Sunshine(函數內部的改變對其沒有影響)
11 print name

?

3.2 可變類型參數

可變類型參數(列表等)指的是:使用可變的數據結構來作為函數的參數使用。在函數內部修改可變類型參數的值時,會同時改變其外部變量的值(因為它們引用的其實是同一個對象),如下所示:

 1 # 列表是可變的
 2 def try_to_change2(n):
 3     n[0] = 'Sunshine'
 4 
 5 person = ['Gumby','Bob']
 6 # 嘗試改變參數的值
 7 try_to_change2(person)
 8 
 9 # output: ['Sunshine', 'Bob']
10 # 函數內部的改變會作用于外部的變量
11 print person

?

如果想避免上面的情況可以對需要作為可變類型的參數的對象復制一個副本,這里是列表可以通過對其進行切片來返回一個新的副本,如下:

 1 # 將可變的數據結構(列表)用作參數
 2 def try_to_change2(n):
 3     n[0] = 'Sunshine'
 4 
 5 person = ['Gumby','Bob']
 6 n = person[:] # 通過切片返回新的副本
 7 try_to_change2(n)
 8 print person # ['Gumby', 'Bob']
 9 print n # ['Sunshine', 'Bob']
10 print n is person # False

?

3.3 關鍵字參數和默認值

在我們之前使用參數的形式是:位置參數,即調用該函數給其傳值時,是根據輸入的值的先后順序來給參數一一賦值 的。不過有時候如果我們需要定義的函數有大量的參數時,傳值時只是于依賴于順序的話是比較容易出錯的。同時如果部分參數在不多數情況下值都是一樣的,每次 調用都需要重新賦值也比較麻煩。針對于這種情況Python為我們提供了兩個語法糖:即關鍵字參數默認值。(PS:C#4.0新增的兩個特性:具名參數和可選參數,和Python的這兩個語法糖很類似,感興趣的同學可以參考這里:《Effective C#》讀書筆記——條目10:使用可選參數減少方法重載的數量<C#語言習慣>)。

使用關鍵字參數不需要對函數進行任何修改,只需要在調用函數時顯示為參數賦值即可(不依賴特定順序),如下:

1 def hello(gretting,name):
2     print "%s,%s!" % (gretting,name)
3 
4 # output: hello,world!
5 hello(name='world',gretting='hello')

?

可以看到雖然調用時代碼變多了,但是每個參數的含義一目了然。不過有時候我們的函數有些參數在大部分情況下使用同樣的值,有時候也需要改變,這時候使用默認值,可以很好的解決這種問題,如下:

1 def hello(gretting = 'hello',name='world'):
2     print "%s,%s!" % (gretting,name)
3 
4 hello() # hello,world!
5 hello(name = 'Sunshine') # hello,Sunshine!
6 hello('Greetings') # Greetings,world!

?可以看到,如果沒有給任何值的話,函數自動使用默認值,也可以通過關鍵字參數指定部分值,其他的依然使用默認參數,這為我們的方法調用提供了很大的靈活性。

?

3.4 使用任意參數列表

前面介紹的參數的個數基本都是固定的,有時候可以接收任意多的參數也是很有必要的,這時候可以使用Python為我們提供的語法糖(*號)來實現:

 1 def print_params(number,*params):
 2     print number
 3     print params
 4 
 5 # output: 
 6 # 6
 7 # (1, 2, 3, 4, 5, 6)
 8 print_params(6,1,2,3,4,5,6)
 9 
10 # output:
11 # 0
12 # ()
13 print_params(0)

?

我們可以看到參數前的*號將所有的值放置到一個元組中(可以理解為將其他的參數收集起來)。如果沒有為*號后的參數賦值則其值為一個空的元組。不過使用一個*號這樣的語法不能處理關鍵字參數,如下:

1 def print_params(*params):
2     print params
3 
4 # TypeError: print_params() got an unexpected keyword argument 'params'
5 print_params(params = (1,2,3))

?

解決的辦法很簡單,使用**來修飾參數即可,如下所示:

1 # -- coding: utf-8 --
2 def print_params(**params):
3     print params
4     print type(params)
5 
6 # output: {'params': (1, 2, 3)}
7 # output: <type 'dict'>
8 print_params(params = (1,2,3))

?可以看到使用**修飾的參數本質上其實是一個字典類型。可以通過這個字典來收集參數。

?

3.5 解包參數列表

除了通過才定義函數的參數(形參)前添加*或者**來收集參數,我們還可以在調用函數時在實參前調解這兩個操作符,它們表示其對應的逆過程。如下所示:

1 def add(x,y):
2     print x + y
3 
4 params = (1,2)
5 
6 # output: 3
7 add(*params)

?

通過使用*操作符我們將params參數分割了add函數所需的兩個參數,同樣我們也可以使用**操作符來分割字典對象:

1 def hello(greeting,name):
2     print '%s,%s' %(greeting,name)
3 
4 params = {'greeting':'hello','name':'world'}
5 
6 # output: hello,world
7 # 這里使用*操作符也是可以的
8 hello(**params)

?

參考資料&進一步閱讀

Python基礎教程(第二版)

Python入門教程——深入函數定義

轉載于:https://www.cnblogs.com/IPrograming/p/Python_function.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/273956.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/273956.shtml
英文地址,請注明出處:http://en.pswp.cn/news/273956.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

求子數組的最大和

窮舉法&#xff1a; int MaxSubArraySum(int a[], int n) { int i, j, MaxSum 0, tmpSum, cnt; for (i1; i<n; i) { for (j0; ji<n; j) { cnt 0; tmpSum 0; while (cnt < i) { tmpSum a[jcnt]; cnt; } if (MaxSum < tmpSum) { MaxSum tmpSum; } } } return Ma…

scrapy框架-post使用

scrapy中使用FormRequest向網頁提交數據 Scrapy post使用 如何post data&#xff1a; http://httpbin.org/post FormRequest : post請求 GitHub Login 借助瀏覽器分析登陸行為。 分析post的內容先嘗試一次錯誤的登陸&#xff1a;如下&#xff1a;分析&#xff1a;需要post…

duilib進階教程 -- 改進窗口拖動 (12)

現在大家應該都知道caption"0,0,0,32"&#xff0c;是指示標題欄區了吧&#xff0c;如果想要整個窗口都能拖動呢&#xff1f; 那直接把高度改成和窗口一樣不就得了~O(∩_∩)O~ 嗯&#xff0c;這樣是可以&#xff0c;比如窗口高度是600&#xff0c;那么我們指定caption…

python- 基礎 range方法的使用

1、第一種用法 index[1,2,0,5,9,8,10,6,4,7] for i in range(len(index)): print(index[i]) 結果&#xff1a; λ py test.py 1 2 0 5 9 8 10 6 4 7 2、第二種用法&#xff1a; index[1,2,0,5,9,8,10,6,4,7] for i in range(0,len(index),2): print(index[i]) 運…

Oracle行列轉換小結

目錄結構如下&#xff1a;行轉列列轉行[一]、行轉列 1.1、初始測試數據 表結構&#xff1a;TEST_TB_GRADE Sql代碼 create table TEST_TB_GRADE ( ID NUMBER(10) not null, USER_NAME VARCHAR2(20 CHAR), COURSE VARCHAR2(20 CHAR), SCORE FLOAT ) 初始…

python- 進階 與flask的搭配使用---定時任務框架APScheduler學習詳解

APScheduler簡介 在平常的工作中幾乎有一半的功能模塊都需要定時任務來推動&#xff0c;例如項目中有一個定時統計程序&#xff0c;定時爬出網站的URL程序&#xff0c;定時檢測釣魚網站的程序等等&#xff0c;都涉及到了關于定時任務的問題&#xff0c;第一時間想到的是利用ti…

Mingw下g++編譯執行順序錯誤

今天寫一個簡單的線性表時&#xff0c;用Mingw中的g編譯、調試、運行時發現一個奇怪的現象&#xff1a;程序的執行順序與實際編寫順序不一致。 編譯環境&#xff1a;代碼編寫 win7下 editplus Mingw 4.3.3 g 代碼片段如下&#xff1a; 1 //function: create a list 2 //ti…

python系統學習1-程序設計的基本方法

一、程序設計基本方法 計算機與程序設計 編譯和解釋 程序的基本編寫方法 計算機編程 1、計算機與程序設計 &#xff08;1&#xff09;、計算機是根據指令操作數據的設備 功能性&#xff1a;對數據的操作、表現為數據計算、輸出輸入處理和結果存儲。 可編程性&#xff1a;…

python 系統學習實例1.1 - 華氏度與攝氏度的轉換

# C ( F - 32 ) / 1.8???????????????????????????????????????????????????????????????????????????????? # F C * 1.8 32?????????????????????????????…

EMS問題

如果EMS啟動后在運行時報出 JMS error: "Not allowed to create destination這個錯誤&#xff0c;可能就是你啟動方式的問題了進入到EMS的安裝目錄的bin目錄下&#xff0c;運行tibemsca.bat那個文件就好使了。轉載于:https://www.cnblogs.com/xiaotianyu/p/3421737.html

python 系統學習實例1.2 - 人民幣與美元的轉換

# RMB USD / 6.78???????????????????????????????????????????????????????????????????????????????? # USD RMB* 6.78 def tempConvert(): t input("請輸入數值:") …

HDTV(1920x1080)碼率和視頻質量關系的研究 2 (實驗結果)

上一篇文章中介紹了實驗的準備工作&#xff0c; HDTV&#xff08;1920x1080&#xff09;碼率和視頻質量關系的研究 1 &#xff08;前期準備&#xff09; 本文介紹一下實驗的結果。 首先來看一下主觀評價的試驗結果&#xff1a; 從實驗結果來看&#xff0c;可以得出以下結論&…

python爬蟲--如何爬取翻頁url不變的網站

參考 https://blog.csdn.net/c350577169/article/details/80410133

POJ 1745 Divisibility DP

POJ:http://poj.org/problem?id1745 A完這題去買福鼎肉片&#xff0c;和舍友去買滴~舍友感慨“這一天可以賣好幾百份&#xff0c;每份就算賺一塊錢。。那么一個月。。一年。。。” 我說“那我們以后去賣這個吧&#xff0c;餓了還能自己煮著吃” 哈哈&#xff0c;一群天真的少…

NGUI如何創建自己的精靈圖集

說實話其實很簡單,但是在不知道的情況下真的不好弄啊. 1. 選擇你要制作精靈圖集的圖片,可以選擇多張 2. 提倡使用快捷鍵Alt Shift M 會有如下窗口彈出,也可以NGUI --> Open-->Atlas Maker打開 我們看到在Sprites里面就是我們選擇的要制作圖集的圖片 當在Replace后面的輸…

C++ - 進階 1002

This time, you are supposed to find AB where A and B are two polynomials. Input Specification: Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial: K N?1?? a?N?1???? N?2??…

修改6S Fortran77 代碼,建立查找表

逐像元大氣校正&#xff0c;常預先計算查找表&#xff08;LUT&#xff0c;LookUp Tabel&#xff09;&#xff0c;6S大氣輻射傳輸模式也可以用來計算LUT。但6S源程序輸出信息多&#xff0c;且浮點數輸出精度低&#xff0c;不利于提取關鍵信息生成LUT&#xff0c;本文描述了怎樣修…

c++ 實例

#include "stdafx.h" #include <iostream> using namespace std; int main() { int a; a 4; cout<<a<<endl; return 0; }

VMware虛擬機與宿主無法復制的解決辦法

由于工作需要&#xff0c;上網機器使用虛擬機&#xff0c;因此需要經常來回的拷貝文件&#xff0c;而vmware從6.5一直走來到10.0.1&#xff0c;總是有一個問題很讓人苦惱---共享粘貼板總是會無故失效。經常實驗&#xff0c;發現可以經過以下方法臨時解決一下&#xff0c;雖然不…

c++ pat 乙級 --1001?害死人不償命的(3n+1)猜想

1001 害死人不償命的(3n1)猜想 &#xff08;15 分&#xff09; 卡拉茲(Callatz)猜想&#xff1a; 對任何一個正整數 n&#xff0c;如果它是偶數&#xff0c;那么把它砍掉一半&#xff1b;如果它是奇數&#xff0c;那么把 (3n1) 砍掉一半。這樣一直反復砍下去&#xff0c;最后…