python學習第五天 —– 函數

1. 內置函數

  例如: print, round

2.自定義函數:

  通過def來定義
def funcname(parameter_list):
    pass
  ⑴.參數parameter_list可以沒有
  ⑵.在函數體重可以通過return返回value,如果沒有返回value,則認為返回None
 
  對於無線遞歸函數,可以設置最大遞歸數量:
import sys
sys.setrecursionlimit(100000)
  sys.setrecursionlimit,系統默認為992
 
  函數是可以返回多個結果的:
def damage(skill1, skill2):
    damage1 = skill1 * 3
    damage2 = skill2 * 2 + 10
    return damage1, damage2
    
damages = damage(3, 6)    
print(type(damages))
//<class 'tuple'>    
  
  我們可以通過【】和序號獲取元組中的某個值。
  我們可以通過兩個變數去接收這兩個返回結果:
def damage(skill1, skill2):
    damage1 = skill1 * 3
    damage2 = skill2 * 2 + 10
    return damage1, damage2
    
skill1_damage, skill2_damage = damage(3, 6)    
print(skill1_damage, skill2_damage) //9 22

3.序列解包與鏈式賦值:

變數的逗號賦值,可以直接將賦值號後的元素們轉換為元組:
d = 1,2,3  
print(d)
# (1, 2, 3)
# <class 'tuple'>
那麼,反過來,就是序列解包:

d = 1,2,3
a, b, c = d
此時可以得到以下程式碼:
a, b, c = 1,2,3
print(a, b, c)
# 1 2 3
解包數量應該與序列長度相等,如下就會報錯:
a, b = [1, 2, 3]
#Traceback (most recent call last):
#  File ".\c4.py", line 12, in <module>
#    a, b = [1, 2, 3]
#ValueError: too many values to unpack (expected 2)
修改長度:
#a, b = [1, 2]
#print(a, b) 
##  1 2

a, b = [1]
Traceback (most recent call last):
  File ".\c4.py", line 12, in <module>
    a, b = [1]
ValueError: not enough values to unpack (expected 2, got 1)
鏈式賦值:
 
a = b = c = 1
print(a, b, c)
#1 1 1

4.必須參數與關鍵字參數:

  必須參數:

  函數參數列表裡定義的參數必須要傳遞的,如果不傳遞,是會報錯的。
  如下列程式碼:
def add(x, y):
    result = x + y
    return result
  調用add函數時必須傳兩個參數,否則,會報錯。
add(1)
# Traceback (most recent call last):
#  File ".\c1.py", line 12, in <module>
    add(1)
# TypeError: add() missing 1 required positional argument: 'y'
  其中,x,y被稱為形參,調用時傳入的數據被稱為實參。

  關鍵字參數:

  可以指明我傳入參數是誰,此時就不需要按照順序去傳入參數。

def add(x, y):
    print(x, y)

c = add(y = 3, x = 2)
# 2 3

 默認參數:

  在形參中賦予默認值。
def print_student_files(name, gender='', age=22, college="華北水利水電大學"):
    print('我叫' + name)
    print('我今年' + str(age) + '歲了')
    print('我是' + gender + '')
    print('我在' + college + '上學')

print_student_files('雞小萌', '', 18, '人民路小學')
print('_______________________________________________')
print_student_files('五六七')
print('_______________________________________________')
print_student_files('果果', age = 17)
結果是:
我叫雞小萌
我今年18歲了
我是男生
我在人民路小學上學
_______________________________________________
我叫五六七
我今年22歲了
我是男生
_______________________________________________
我叫果果
我今年17歲了
我是男生
我在華北水利水電大學上學
  注意:
    如果要設置默認參數,則所有的必須參數都要放在前邊,所有的默認參數都放在後邊。同時必須參數和默認參數也不能混著給。
print_student_files('果果', gender = '', 17, college='牛津中學')

File "c6.py", line 13
    print_student_files('果果', gender = '', 17, college='牛津中學')
                                                  ^
SyntaxError: positional argument follows keyword argument

  可變參數:

    *號可以將參數組成元組,且如果有必須參數的話,必須參數必須放在前邊。
def demo(*param):
    print(param)
    print(type(param))

demo(1,2,3,4,5,6)
#結果:
#(1, 2, 3, 4, 5, 6)
#<class 'tuple'>
  而且,*號可以將實參進行平鋪,即元組轉換為一個個元素:
def demo(*param):
    print(param)
    print(type(param))

a = (1, 2, 3, 4, 5, 6)
demo(*a)
對於實參:

def demo(param1, *param, param2 = 2):
    print(param1)
    print(param2)
    print(param)

demo('a', 1,2,3, param2 = '3')

#a
#3
#(1, 2, 3)

 關鍵字可變參數:

   用兩個*號去將關鍵字參數轉為字典。
def city_temp(**param):
    print(param)
    print(type(param))
    pass

city_temp(bj = '32', xm = '23', sh = '31')

#{'bj': '32', 'xm': '23', 'sh': '31'}
#<class 'dict'>
  遍歷字典:
    以下是錯誤遍歷:
def city_temp(**param):
    for key, value in param:
        print(key, ':', value)

city_temp(bj = '32', xm = '23', sh = '31')

#b : j
#x : m
#s : h
  正確遍歷字典:
def city_temp(**param):
    for key, value in param.items():
        print(key, ':', value)

city_temp(bj = '32', xm = '23', sh = '31')

#bj : 32
#xm : 23
#sh : 31
  對於字典的反向輸入:
def city_temp(**param):
    for key, value in param.items():
        print(key, ':', value)

a = {'bj': '32c', 'sh':'31c'}
city_temp(**a)

#PS F:\pythonlearn\Demo\eight> python .\c8.py
# bj : 32c
#sh : 31c

 5.變數作用域:

      此處可以看到與javascript中的作用域有很大的不同。先來看程式碼:

c = 50  

def add(x, y):
    c = x + y
    print(c)

add(1, 2)
print(c) 
#3
#50
  七月給的解釋:函數內的c和函數外的c不是一個變數,相當於重新命名了一個變數a,然後列印a,與外邊的c沒有一點關係。

 

  然鵝,函數內部可以調用函數外部的變數,那麼問題來了:
c = 10

def demo():
    print(c)

demo() #10
  for循環內定義的數據可以在for循環以外使用么?
def demo():
    c = 50

    for i in range(0, 9):
        a = 'a'
        c += 1
    print(c)
    print(a)

demo()

#59
#a
  也就是說,在python中for循環等循環體內並不構成作用域。即,python中並沒有塊兒級作用域。
 

6.作用域鏈:

  個人理解是:一個變數的值等於他所在的作用域中離得最近最小的作用域。即,所在作用域沒有改變數,則向上級作用域查找,直到找到為止。
 
c = 1

def func1():
    c = 2
    def func2():
        c = 3
        print(c)
    func2()

func1()

//依次將 c = 3, c = 2這兩行程式碼注釋,得到列印的結果分別是3, 2, 1

 

7.global關鍵字:

    可以通過global關鍵字將局部變數變為全局變數(變數會不會污染呢,我覺得不應該過多使用,或者說盡量不用)
def demo():
    global c
    c = 2

demo()

print(c) 
#2
個人測試,c10.py中寫入上邊程式碼,c11.py文件中導入
import c10
print(c10.c) //2
此時是可以列印出C的結果,然鵝,修改c11文件,
import c10
print(c) //c是未定義,因此,這個c並不是在項目中全局