06、python 系列之--函數

fun.png

版權聲明:本文為博主原創文章,未經博主允許不得轉載。

PS:轉載請注明出處
作者: TigerChain
地址: http://www.lxweimin.com/p/105ee1470d02
本文出自 TigerChain簡書 Python 系列

教程簡介

  • 1、閱讀對象

本篇教程適合新手閱讀,老手直接略過

正文

一、什么是函數

1、定義

在編程中,函數是對實現特定功能,并且可以重復使用的一個代碼片段。比如 python 的內置函數 print(),函數的作用:

  • 1、封裝代碼
  • 2、降低耦合
  • 3、方便復用
  • 4、方便閱讀

2、定義函數的格式

def 函數名(參數...):
    函數體
    ...

ps:函數體以 : 號開始,并且縮進

比如定義一個 返回 a+b 的函數

def add(a,b):
    return a+b

這樣就自定義了一個函數。

函數調用:add(5,6) 即可

demo1:將后一個姓名列表添加到第一個列表的末尾


names = ["tigerchain","xiaoming","liubing"]

print("原始的姓名列表是:%s"%names)

# ?定義函數 
def appendList(lists):
    names.append(lists)
    print("添加后的姓名列表是:%s"%names)

new_names = ["sulei","xiaozhang"]
appendList(new_names)

print("最終的姓名列表是: %s "%names)

運行查看結果:

? python 01、函數的基本用法.py
原始的姓名列表是:['tigerchain', 'xiaoming', 'liubing']
添加后的姓名列表是:['tigerchain', 'xiaoming', 'liubing', ['sulei', 'xiaozhang']]
最終的姓名列表是: ['tigerchain', 'xiaoming', 'liubing', ['sulei', 'xiaozhang']]

二、函數的參數

1、形參和實參

首先我們要明確一點 python 中傳遞參數是按址傳遞的,也就是把變量的引用傳遞進去,而不是按值傳遞

  • 1、定義函數后面的()中的參數稱為形參
  • 2、調用函數的方法,傳遞給函數的參數稱為實參

比如:定義一個函數

def addsub(a,b):
    return a+b

其中 a 和 b 是形參

調用方法 addsub(1,5),其中 1,5 就是實參

2、理論上函數可以傳遞無數個參數,但是不建議這樣干,如果多個參數,就想辦法抽取多個方法

def 方法名(形參1,形參2,...,形參n)

demo2:定義一個函數,輸入三條邊,看其能不能組成三角形

def sanjiao(x,y,z):#實際開發中不要使用拼音作為函數名
    if(x+y>z and x+z>y and y+z>x):
        print("%d,%d,%d 可以組成三角形"%(x,y,z))
        if(x==y==z):
            print("并且這是一個等邊三角形")
        elif(x==y or y==z or x==z):
            print("并且這是一個等腰三角形")
        elif(x*x+y*y==z*z or y*y+z*z==x*x or x*x+z*z==y*y):
            print("并且這是一個直角三角形")
        else:
            print("并且這是一個普通的其解形")
    else:
        print("不好意思,你三角形的概念好好學學吧,不能構成三角形")

print("請輸入三角形的三條邊")

x = raw_input("第一條邊:")
y = raw_input("第二條邊:")
z = raw_input("第三條邊:")

sanjiao(int(x),int(y),int(z))

運行查看結果:

fun_sanjiao.gif

demo3:輸入三個數,輸出最大數

def getMax(x,y,z):
    max = x
    if(y>max):
        max=y
        if(z>max):
            max=z

    return max

a = raw_input("請輸入第一個數:")
b = raw_input("請輸入第二個數:")
c = raw_input("請輸入第三個數:")

print("%d,%d,%d 中最大的數是:%d"%(int(a),int(b),int(c),getMax(int(a),int(b),int(c))))

運行查看結果:

? python 02、形參和實參.py
請輸入第一個數:4
請輸入第二個數:8
請輸入第三個數:0
4,8,0 中最大的數是:8

3、變量的作用域

定義在函數體中的變量只能在本函數中有效,出了函數以后就不能被訪問

demo1:變量的作用域

def add(x,y):
    z = x+y
    print z
def new_add():
    print("===1====")
    z+=4
    print("===3===")
    print z

add(1,2)
new_add()

運行查看結果:

? python 04、變量作用域.py
3
===1====
Traceback (most recent call last):
  File "04、變量作用域.py", line 13, in <module>
    new_add()
  File "04、變量作用域.py", line 8, in new_add
    z+=4
UnboundLocalError: local variable 'z' referenced before assignment

掛掉了,問題出在 new_add() 方法中的 z+=4,看 error 大概意思就是不能訪問之前在 add 方法中定義的 z 變量

三、函數的文檔「注釋」

我們知道多行注釋使用 ''' ''' ,函數的文檔是什么呢?就是用來描述函數的語句,但是不會被編譯,不能使用 # 注釋

demo1:對 add 函數作文檔說明

'''
    demo1:對add 函數作文檔說明
'''
def addFun(a,b):
    ''' 這個函數是返回兩個整數的和 '''
    return a+b
'''help(addFun) 顯示方法體中的文檔說明'''
print __doc__

運行查看結果:

? python 03、函數的文檔.py


    demo1:對add 函數作文檔說明

2、局部變量和全局變量

1、局部變量:局部變量是針對方法而說的,沒有方法局部變量就沒有意義,定義在方法體中的變量我們稱為局部變量,局部變量只能在方法體中被仿問,在方法體外是不能被仿問的。

2、全局變量:定義在方法調用之前的變量,我們稱為全局變量,全局變量,所有方法都要以仿問

demo2:以下 demo1 中的 x 是修改全局變量 x 還是定義了一個局部變量 x 呢?

x = 0
def demo1():
    x = 100
    print("x 的值是%d "%x)
def demo2():
    print("x 的值是%d "%x)
    pass

demo1()
demo2()

運行查看結果:

? python 04、變量作用域.py
x 的值是100
x 的值是0

可以看到在 demo1 方法中的變量 x 就是定義一個局部變量,對全局變量 x 一點毛影響也沒有。那么,我們如何讓 demo1 中的 x 就是修改全局變量 x 呢?,使用 global 關建字來聲明即可

稍微修改上面的代碼在 demo1 x = 100 之前加入 global x

global x
x = 100

繼續運行查看結果:

? python 04、變量作用域.py
x 的值是100
x 的值是100

可以看到我們成功的修改了全局變量。

demo3:可變類型變量例子

# 定義一個列表「可變類型」
a = [1,2,3,4]

def demo1():
    a.append(5)
    print("a 的內容是 %s"%a)
def demo2():
    print("a 的內容是 %s"%a)
    pass
demo1()
demo2()

運行查看結果:

? python 04、變量作用域.py
a 的內容是 [1, 2, 3, 4, 5]
a 的內容是 [1, 2, 3, 4, 5]

我們可以看到,執行 demo1() 我們就修改了列表,所以如果聲明的是列表類型的變量,我們就可以直接修改

四、函數的參數(二)

1、缺省參數

缺省參數,就是我們可以給函數默認設置參數,格式如下:

def 方法名(參數1,參數2,...,參數n = 值)

PS:在這里一定要注意一點,缺省參數一定要放在參數列表的最后面

demo1:定義函數 demo1(),并且帶有兩個參數姓名和年齡,并且姓名是默認值是'TigerChain',輸入看結果

# -*- coding:utf-8 -*-

'''
    demo1:缺省參數 
'''

def demo1(age,name='TigerChain'):
    print("name = %s"%name)
    print("age = %d"%age)
demo1(12)

運行查看結果:

? python 05、函數的參數.py
name = TigerChain
age = 12

從上面的 demo 中我們可以看到,如果我們沒有給默認值的參數傳值的話,就會使用默認值,如果我們傳遞了呢?答案肯定是按傳遞的值顯示,修改上面代碼,只是把調用方法改為 demo(12,'TigerChain001')

查看結果

? python 05、函數的參數.py
name = TigerChain001
age = 12

2、不定長參數

我們知道函數的參數理論上可以有無數個,如果一個函數要處理比聲明時更多的參數,這就叫做不定長參數,在傳遞的時候才會確定參數的多少,格式如下:

def 方法名(參數1,參數2,*參數3,**參數4):
    方法體

PS:其中參數 1 和參數 2 沒有什么說的,就是普通的參數,參數 3 傳遞進來的會被錄作元組存起來,參數 4 「兩個 **」傳遞的是字典

demo2:可變參數 1

def demo2(param1,param2,*param3):
    print "param1 = ",param1
    print "param2 = ",param2
    print "param3 = ",param3
demo2(1,2,3,4,5,6)

運行查看結果:

? python 05、函數的參數.py
param1 =  1
param2 =  2
param3 =  (3, 4, 5, 6)

我們可以看到 3,4,5,6 被當作元組傳傳遞過來

  • 我們修改上面的代碼
def demo3(param1,param2,*param3,**param4):
    print "param1 = ",param1
    print "param2 = ",param2
    print "param3 = ",param3
    for key,value in param4.items():
        print key ," = ",value

demo3(1,2,3,4,5,name='TigerChain',age=12,address='中國')

運行查看結果:

? python 05、函數的參數.py
param1 =  1
param2 =  2
param3 =  (3, 4, 5)
age  =  12
name  =  TigerChain
address  =  中國
  • 續續修改上面的代碼,我們把調用方式改一下
c = (7,8,9)
d = {"name":"TigerChain","age":12,"sex":"男"}
demo3(1,2,3,c,d)

運行查看結果:

? python 05、函數的參數.py
param1 =  1
param2 =  2
param3 =  (3, (7, 8, 9), {'age': 12, 'name': 'TigerChain', 'sex': '男'})

我們可以看到 c 「元組」 和 d 「字典」 整體被當做元組傳到 param3 中了

  • 再修改上面的代碼

這次我們在上面代碼基礎上,只是修改調用方式

demo3(1,2,3,*c,**d)

運行查看結果:

? python 05、函數的參數.py
param1 =  1
param2 =  2
param3 =  (3, 7, 8, 9)
age  =  12
name  =  TigerChain
sex  =  男

3、模擬用戶注冊登錄「函數版」

demo:用戶注冊登錄,并且用戶名密碼輸入錯誤三次,鎖定

# -*- coding:utf-8 -*-

'''
    這是一個函數版模擬用戶注冊登錄
'''

# 定義保存用戶名和密碼的字典
userInfo = {}

# 是否登錄的標志
islog = False

# 注冊方法
def register():
    uname = raw_input("添加用戶名: ")
    upass = raw_input("添加密碼: ")
    userInfo[str(uname)] = upass
    print("注冊成功")

# 登錄方法
def login():
    for i in range(3):
        global islog
        if(islog):
            break
        username_input = raw_input('請輸入用戶名:')
        userpass_input = raw_input("請輸入密碼:")
        login_count = 2-i  # 判斷還能輸入多少次。
        for key in userInfo.keys():
            if(str(username_input) == key and userInfo[key]== userpass_input):
                print("歡迎 %s 登錄"%key)
                islog = True
                break
            else:
                # 最后一次是 0 不再提示
                if login_count != 0:
                    print("用戶名或密碼錯誤,還可以輸入 %d 次"%login_count)
        if(i==2):
            print("登錄超過 3 次,半個小時后再登錄")


register()
login()

運行查看結果:

login_fun.gif

五、匿名函數

什么是匿名函數,顧名思義就是沒有名字的函數

在 python 中使用 lambda 關建字來創建匿名函數「lambda 是一個表達多,不是一個語句」,格式如下:

lambda [arg1 [,arg2,.....argn]]:expression

demo1:使用 lambda 來創建一個加法運算函數

# 定義一個 labmda 表達式
sum = lambda a,b:a+b
print sum(1,4)

運行查看結果:

? python 07、匿名函數.py
5

demo2:使用 lambda 作為方法參數「函數式編程」

# 定義一個函數,參數分別是普通變量和一個函數
def fun(a,b,func):
    return func(a,b)
result = 0

e = ''

while True:
    if e=='e':
        break
    if e == 'c' or e =='':
        a = int(raw_input("請輸入一個整數 a = "))
        b = int(raw_input("請輸入一個整數 b = "))
        calc = raw_input("選擇 + - * / 其中一項:")
        # 加法運算
        if calc == '+':
            result = fun(a,b,lambda a,b:a+b)
        # 減法運算
        elif calc == '-':
            result = fun(a,b,lambda a,b:a-b)
        # 乘法運算
        elif calc == "*":
            result = fun(a,b,lambda a,b:a*b)
        else:
        # 除法運算
            if b==0:
                print("被除數不能為0")
                continue 
            result = fun(a,b,lambda a,b:a/b)
        print result
        e = raw_input("退出請輸入 e 繼續請輸入 c : ")

運行查看結果:

python 07、匿名函數.py
lambda.gif

到此為止,我們就把函數的一些方法和功能基本介紹完了

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • //Clojure入門教程: Clojure – Functional Programming for the J...
    葡萄喃喃囈語閱讀 3,776評論 0 7
  • 有些人這樣說的,農村的孩子與城市里的孩子相比,缺少禮貌,的確,我經過觀察確實如此。在小的時候,城里的父母經常...
    心如山亦如水閱讀 293評論 0 0
  • 經過這一段時間的學習,讓我對創意有了更深的了解,現在我按個人的理解,重新定義了創意大師,總結了創意的三種境界,簡稱...
    醒時做夢閱讀 404評論 0 2
  • 友人向我推薦夏達的《子不語》最近看了看,有點感觸。權且寫下來當做記憶吧,也可說是感思。 終于可以表達一下自己的看法...
    曾經未來的我閱讀 636評論 0 0
  • 第一篇是羅丹琳小朋友寫的放風箏日記,這個小朋友寫出了這個冬天放風箏的別樣心情,誰說冬天就不適合放風箏呢 第二篇...
    fdeceb686cba閱讀 253評論 0 0