1. 程式人生 > >Python入門學習-DAY09-函數基礎與參數

Python入門學習-DAY09-函數基礎與參數

表達式 長度 解決 %s true gist wrap bsp 元組

函數基礎

一 定義函數的三種形式

1.1 無參函數
def foo():
  print(‘from foo‘)
foo()

1.2 有參函數
def bar(x,y):
  print(x,y)
bar(1,2)

1.3 空函數
def func():
  pass

def upload():
  pass

def download():
  pass

def login():
  pass

def register():
  pass

def ls():
  pass

二 調用函數的三種形式


2.1 語句形式
def foo():
  print(‘from foo‘)
foo()

2.2 表達式形式
def foo(x,y):
  res = x + y
return res

res=foo(1,2) 表達式形式
res1=foo(1,2)*100
print(res1)

2.3 可以當作參數傳給另外一個函數
def max2(x,y):
  if x > y:
    return x
  else:
    return y

res=max2(max2(1,2),3)
print(res)

函數返回值

一 函數的返回值需要註意:

1 返回值沒有類型限制
2 返回值沒有個數限制
返回1個值:調用函數拿到的結果就是一個值
返回多個值:調用函數拿到的結果就是一個元組
返回0個值,或者不寫return:調用函數拿到的結果就是None

二 return關鍵字:

return是函數結束的標誌,函數內可以有多個return,但只要執行一次,整個函數就結束

def f1():
  print(‘first‘)
return 1
  print(‘second‘)
return 2
  print(‘third‘)
return 3

res=f1()
print(res)

def foo():
  count=1
  while True:
    print(count)
    if count == 3:
      return
    count+=1

foo()

def bar():
  pass

def foo():
  return [1,2],1,1.3,{‘x‘:1},bar

res=foo()
print(res)

def func():
  print(‘from foo‘)
return

res=func()
print(res)

函數的參數

函數的參數分為兩大類:

1 形參: 指的是在定義函數階段括號內指定變量名,即形參本質就是"變量名"

2 實參: 指的是在調用函數階段括號內傳入的值,即實參本質就是"值"

形參與實參的關系:在調用函數時,會將實參(值)賦值(綁定)給形參(變量名),
這種綁定關系在函數調用時臨時生效,在調用結束後就失效了
def foo(x,y): #x=1 y=2
  x=1
  y=2
  print(x,y)

foo(1,2)

形參與實參的具體分類


一 位置參數


1.1 位置形參: 在定義函數階段按照從左到右的順序依次定義的形參,稱之為位置形參
註意:但凡按照位置定義的形參,必須被傳值,多一個不行,少一個也不行
def foo(x,y):
  print(x,y)
foo(1,2)#1,2
foo(1,2,3)#多,報錯
foo(1,)#少,報錯

1.2 位置實參: 在調用函數階段按照從左到右的順序依次傳入的值,稱之為位置實參
註意:但凡按照位置定義的實參,會與形參一一對應
def foo(x,y):
  print(x,y)

foo(2,1)

二 關鍵字參數

關鍵字實參: 在調用函數階段,按照key=value的形式指名道姓地為形參傳值
註意:
1. 可以完全打亂順序,但仍然能指名道姓為指定的形參傳值
2. 可以混合使用位置實參與關鍵字實參,但是必須註意:
2.1 位置實參必須放到關鍵字實參前面
2.2 不能對一個形參重復賦值
def foo(name,age):
  print(name,age)

foo(‘egon‘,18)#name=‘egon‘ age=18
foo(18,‘egon‘)#name=‘18 age=‘egon‘
foo(age=18,name=‘egon‘)#name=‘egon‘ age=18

foo(‘egon‘,age=18)#name=‘egon‘ age=18
foo(name=‘egon‘,18)#報錯
foo(‘egon‘,age=18,name=‘lxx‘)#報錯

三 默認參數

默認參數:指的是在定義函數階段,就已經為某個形參賦值了,改形參稱之為有默認值的形參,簡稱默認形參
註意:
1. 在定義階段就已經被賦值,意味著在調用階段可以不用為其賦值
2. 位置形參應該放到默認形參前面
3. 默認參數的值在函數定義階段就已經固定死了
4. 默認參數的值通常應該是不可變類型

def foo(x,y=2):
  print(x,y)

foo(1)#x=1,y=2
foo(1,3)#x=1,y=3
foo(y=3,x=1)#x=1,y=3

m=10
def foo(x,y=m):#y=m=10
  print(x,y)

m=20
foo(1) #x=1,y=10


def register(name,hobby,l=[]):
  l.append(hobby)
  print(‘%s 的愛好為 %s‘ %(name,l))

register(‘alex‘,‘piao‘)
register(‘lxx‘,‘喝腰子湯‘)
register(‘yxx‘,‘不洗澡‘)
register(‘egon‘,‘read‘)

alex 的愛好為 [‘piao‘]
lxx 的愛好為 [‘piao‘, ‘喝腰子湯‘]
yxx 的愛好為 [‘piao‘, ‘喝腰子湯‘, ‘不洗澡‘]
egon 的愛好為 [‘piao‘, ‘喝腰子湯‘, ‘不洗澡‘, ‘read‘]

def register(name, hobby, l=None):
  if l is None:
    l=[]
    l.append(hobby)
  print(‘%s 的愛好為 %s‘ % (name, l))

register(‘alex‘, ‘piao‘)
register(‘lxx‘, ‘喝腰子湯‘)
register(‘yxx‘, ‘不洗澡‘)
register(‘egon‘, ‘read‘)

alex 的愛好為 [‘piao‘]
lxx 的愛好為 [‘喝腰子湯‘]
yxx 的愛好為 [‘不洗澡‘]
egon 的愛好為 [‘read‘]

位置形參vs默認形參

對於大多情況下傳的值都不相同的,應該定義成位置形參
對於大多情況下傳的值都相同的,應該定義成默認形參

def register(name,age,sex=‘男‘):
  print(name,age,sex)

register(‘李鐵蛋‘,18,)
register(‘李銀蛋‘,28)
register(‘張銅蛋‘,38)
register(‘劉鹵蛋‘,48)
register(‘劉二丫‘,19,‘女‘)

李鐵蛋 18 男
李銀蛋 28 男
張銅蛋 38 男
劉鹵蛋 48 男
劉二丫 19 女


四 可變長度的參數

站在實參的角度,參數長度可變指的是在調用函數時,傳入的實參值的個數不固定
而實參的定義方式無法兩種:位置實參,關鍵字實參,對應著形參也必須有兩種解決方案*與**,類分別應對溢出的位置實參與關鍵字實參

1. 在形參中帶*:會將調用函數時溢出位置實參保存成元組的形式,然後賦值*後的變量名

def foo(x,y,*z): #z=(3,4,5,6)
  print(x,y,z)

foo(1,2,3,4,5,6)

2. 在實參中帶*: 但凡在實參中帶*星的,在傳值前都先將其打散成位置實參,再進行賦值

def foo(x,y,*z): #z=(3,4,5,6)
print(x,y,z)
foo(1,*[2,3,4,5,6]) #foo(1,2,3,4,5,6)

def foo(x,y,z):
  print(x,y,z)
foo(1,*(2,3,4,5,6)) #foo(1,2,3,4,5,6)
foo(*(1,2,3)) #foo(1,2,3)
foo(*‘hello‘)# foo()
foo(*‘abc‘) #foo(‘a‘,‘b‘,‘c‘)


3. 在形參中帶**:會將調用函數時溢出關鍵字實參保存成字典的形式,然後賦值**後的變量名

def foo(x,y,**z): #z={‘z‘:3,‘a‘:1,‘b‘:2}
  print(x,y,z)

foo(1,y=2,a=1,b=2,c=3)

4. 在實參中帶**: 但凡在實參中帶**星的,在傳值前都先將其打散成關鍵字實參,再進行賦值

def foo(x,y,**z):# z={‘a‘:100,‘b‘:200}
  print(x,y,z)

foo(1,**{‘a‘:100,‘b‘:200,‘y‘:111})# foo(1,b=200,a=100,y=111)


def foo(x,y,z):
  print(x,y,z)

foo(**{‘y‘:111,‘x‘:222,‘z‘:333})# foo(z=333,x=222,y=111)


5. 規範: 在形參中帶*與**的,*後的變量名應該為args,**後跟的變量名應該時kwargs

def foo(*args,**kwargs): #args=(1,2,3,4,5) kwargs={‘a‘:1,‘b‘:2,‘c‘:3}
  print(args)
  print(kwargs)
foo(1,2,3,4,5,a=1,b=2,c=3)


def bar(x,y,z):
  print(x,y,z)

def wrapper(*args,**kwargs): #args=(1,2,3,4,5,6) kwargs={‘a‘:1,‘b‘:2,‘c‘:3}
  bar(*args,**kwargs)
  bar(*(1,2,3,4,5,6),**{‘a‘:1,‘b‘:2,‘c‘:3}) #bar(1,2,3,4,5,6,a=1,b=2,c=3)
wrapper(1,2,3,4,5,6,a=1,b=2,c=3)

!!!!!!!!!!!!!!!當我們想要將傳給一個函數的參數格式原方不動地轉嫁給其內部的一個函數,應該使用下面這種形式
def bar(x,y,z):
  print(x,y,z)

def wrapper(*args,**kwargs): #args=(1,2) kwargs={‘z‘:3}
  bar(*args,**kwargs)
  bar(*(1,2),**{‘z‘:3}) #bar(1,2,z=3)
wrapper(1,2,z=3) #雖然調用的是wrapper,但是要遵循的確是bar的參數標準

五 命名關鍵字參數: 放到*與**之間的參數稱之為命名關鍵字參數


註意: 命名關鍵字參數必須按照key=value的形式傳值
def foo(x,y,*args,m,n,**kwargs): #args=(3,4,5,6,7,8)
  print(x,y)# 1,2
  print(args)# (3,4,5,6,7,8)
  print(m,n) #222,333
  print(kwargs)

foo(1,2,3,4,5,6,7,8,n=333,m=222,a=1,b=2)


def foo(*,x=1,y):
  print(x)
  print(y)

foo(y=2222,x=1111)

1111
2222

foo(y=2222)

1
2222

Python入門學習-DAY09-函數基礎與參數