1. 程式人生 > >Python基礎(6)_函數

Python基礎(6)_函數

傳遞 獲得 不執行 分配 參數 code else turn 依賴

一 為何要有函數?

不加區分地將所有功能的代碼壘到一起,問題是:

  代碼可讀性差
  代碼冗余
  代碼可擴展差

如何解決?
  函數即工具,事先準備工具的過程是定義函數,拿來就用指的就是函數調用

  結論:函數使用必須是:先定義,後調用

python中函數定義方法:

    def test(x):
    "The function definitions"
    x+=1
    return x


  def:定義函數的關鍵字
  test:函數名
  ():內可定義形參
  "":文檔描述(非必要,但是強烈建議為你的函數添加描述信息)
  x+=1:泛指代碼塊或程序處理邏輯
  return:定義返回值

調用運行:可以帶參數也可以不帶
函數名()

二:函數的分類

  1.內置函數:built-in
  2.自定義函數:
    def 函數名(參數1,參數2,...):
      ‘‘‘註釋‘‘‘
      函數體

函數的使用:先定義,後調用
如何定義函數之定義函數的三種形式
1 定義無參函數:函數的執行不依賴於調用者傳入的參數就能執行時,需要定義為無參函數

def print_tag():
print(‘*************************‘)


def main():
print_tag(‘*‘,20,3)
print_msg(‘hello world‘)
print_tag(‘*‘,20,3)

main()

2 定義有參數:函數的執行需要依賴於調用者傳入的參數才能執行時,需要定義為有參函數

def print_tag(tag,count,line_num):
for i in range(line_num):
print(tag*count)

3 定義空函數:函數體為pass

def func(x,y,z):
pass

三:函數的使用原則
  函數的使用必須遵循:先定義後使用的原則
  函數的定義,與變量的定義是相似的,如果沒有事先定義函數而直接引用就相當於在引用一個不存在變量名  

#定義階段:只檢測語法,不執行代碼

def func():
if 1>2
print(‘hahahahahahah‘)
def func():       #語法沒問題,邏輯有問題,引用一個不存在的變量名
asdfasdfasdfasdfasdf

#調用階段

foo()

返回值:可以返回任意類型

沒有return:None
return value: value
return val1,val2,val3 :(val1,val2,val3)

return的效果:只能返回一次值,終止函數的執行

返回值:

返回值數=0:返回None

返回值數=1:返回object

返回值數>1:返回tuple

四:函數參數

技術分享

1.形參變量只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只在函數內部有效。函數調用結束返回主調用函數後則不能再使用該形參變量

2.實參可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使參數獲得確定值

3.位置參數和關鍵字(標準調用:實參與形參位置一一對應;關鍵字調用:位置無需固定)

4.默認參數

5.參數組

函數參數分類:

1、位置參數(形參、實參)

位置參數:按照從左到右的順序依次定義的參數
  def foo(x,y):
  print(x)
  print(y)
按位置定義的形參,必須被傳值,多一個不行,少一個也不行
  foo(1,2,3)===>報錯
按位置定義的實參,與形參一一對應
  foo(2,10)

2、關鍵字參數 (實參)

關鍵字參數:實參在定義時,按照key=value形式定義
  def foo(x,y):
  print(x)
  print(y)
  # foo(y=10,x=1)
  foo(y=10,x=1) #關鍵字參數可以不用像位置實參一樣與形參一一對應,指名道姓地傳值

  # foo(1,z=20,10) ===>報錯

  # foo(1,y=2,z=10) ===>報錯

註意的問題一:位置實參必須在關鍵字實參的前面
註意的問題二:實參的形式既可以用位置實參又可以是關鍵字實參,但是一個形參不能重復傳值

3、默認參數(形參)

默認參數:在定義函數階段,就已經為形參賦值,定義階段有值,調用階段可以不用傳值

定義:

# def func(x,y=10):
# print(x)
# print(y)

調用:

# func(1,20)
# func(1)

# def func(y=10,x):
# print(x)
# print(y)

形參的應用:值經常變化的需要定義成位置形參,值大多數情況下都一樣,需要定義成默認參數

默認參數需要註意的問題一:必須放在位置形參後面
默認參數需要註意的問題二:默認參數通常要定義成不可變類型
默認參數需要註意的問題三:默認參數只在定義階段被賦值一次

4、可變長參數

可變長參數:可變長指的是實參的個數不固定

按位置定義的非關鍵字可變長度的實參:*     *args

按關鍵字定義的可變長度的實參:** **kwargs

非關鍵字可變長度的實參:*

定義一個函數的時候,必須要預先定義這個函數需要多少個參數(或者說可以接受多少個參數)。一般情況下這是沒問題的,但是也有在定義函數的時候,不能知道參數個數的情況(想一想C語言裏的printf函數),在Python裏,帶*的參數就是用來接受可變數量參數的。看一個例子

def funcD(a, b, *c):
print a
print b
print "length of c is: %d " % len(c)
print c
調用funcD(1, 2, 3, 4, 5, 6)結果是
1
2
length of c is: 4
(3, 4, 5, 6)

  前面兩個參數被a、b接受了,剩下的4個參數,全部被c接受了,c在這裏是一個tuple。我們在調用funcD的時候,至少要傳遞2個參數,2個以上的參數,都放到c裏了,如果只有兩個參數,那麽c就是一個empty tuple。

關鍵字定義的可變長度的實參:**

  如果一個函數定義中的最後一個形參有 ** (雙星號)前綴,所有正常形參之外的其他的關鍵字參數都將被放置在一個字典中傳遞給函數,比如:

def funcF(a, **b):
print a
for x in b:
print x + ": " + str(b[x])
調用funcF(100, c=‘你好‘, b=200),執行結果
100
c: 你好
b: 200

  大家可以看到,b是一個dict對象實例,它接受了關鍵字參數b和c。

結合一起使用:

# def wrapper(*args,**kwargs): #可以接受任意形式,任意長度的參數
# print(args)
# print(kwargs)
#
#
# wrapper(1,2,3,3,3,3,3,x=1,y=2,z=3) ===>(1,2,3,3,3,3,3,) {‘x‘:1,‘y‘=2,‘z‘=3}

命名關鍵字參數:定義在*後的形參,必須被傳值,而且要求實參必須是以關鍵字的形式來傳值

即:

  形參: *args,z=10

或:

  實參:z=10

# def func(x,y=1,*args,z,**kwargs):
# print(x)
# print(y)
# print(args)
# print(z)
# print(kwargs)
#
# func(1,2,3,4,5,z=10,a=1,b=2)

結果:

技術分享

# def func(x,*args,z=1,**kwargs):
# print(x)
# print(args)
# print(z)
# print(kwargs)
#
# func(1,2,3,4,5,a=1,b=2,c=3)

結果:

技術分享

總結:形參:位置形參,默認參數,*args,命名關鍵字參數,**kwargs

五、函數嵌套

#函數的嵌套調用
#
# def max2(x,y):
# if x > y:
# return x
# else:
# return y
#
# def max4(a,b,c,d):
# res1=max2(a,b) #23
# res2=max2(res1,c) #23
# res3=max2(res2,d) #31
# return res3
#
#
# print(max4(11,23,-7,31))


#函數的嵌套定義
def f1():
def f2():
def f3():
print(‘from f3‘)
print(‘from f2‘)
f3()
print(‘from f1‘)
f2()
# print(f1)
f1()

‘‘‘
from f1
from f2
from f3

‘‘‘

六、命名空間

名字空間:存放名字與值的綁定關系

名稱空間分為三種

  內置名稱空間:python解釋器自帶的名字,python解釋器啟動就會生成

  全局名稱空間:文件級別定義的名字都會存放與全局名稱空間,執行python文件時會產生

  局部名稱空間:定義在函數內部的名字,局部名稱空間只有在調用函數時才會生效,函數調用結束則失效

三者的加載順序:內置名稱空間->全局名稱空間->局部名稱空間

三者的取值順序:局部名稱空間->全局名稱空間->內置名稱空間

七、作用域

作用域:

作用範圍:

全局作用域:內置名稱空間與全局名稱空間的名字屬於全局範圍,
        #在整個文件的任意位置都能被引用,全局有效
局部作用域:局部名稱空間的名字屬於局部範圍,
        #只在函數內部可以被引用,局部有效

作用域在定義函數時就已經固定住了,不會隨著調用位置的改變而改變

 1 name=alex
 2 def foo():
 3     name=lhf
 4     def bar():
 5         name=wupeiqi
 6         print(name)
 7         def tt():
 8             name=hedeyong
 9             print(name)
10         return tt
11     return bar
12 
13 func=foo()
14 func()()       #==> bar()() ==>tt()
  ‘‘‘
  hedeyong
  ‘‘‘

Python基礎(6)_函數