py-函数基础
定義: 函數是指將一組語句的集合通過一個名字(函數名)封裝起來,要想執行這個函數,只需調用其函數名即可
特性:
1.減少重復代碼2.使程序變的可擴展3.使程序變得易維護
函數參數
形參變量
只有在被調用時才分配內存單元,在調用結束時,即刻釋放所分配的內存單元。因此,形參只在函數內部有效。函數調用結束返回主調用函數后則不能再使用該形參變量
實參可以是常量、變量、表達式、函數等,無論實參是何種類型的量,在進行函數調用時,它們都必須有確定的值,以便把這些值傳送給形參。因此應預先用賦值,輸入等辦法使參數獲得確定值
def calc(x,y): # x,y 是形參,用來接受參數 res = x*y return rest = calc(2,3) # 2,3 是實參,實際傳入的參數, print(t)默認參數
def staff(name,age,skill,year=2018): #默認參數一般放到實參后面print('staff info'.center(20,'-'))print("name:",name)print("age:",age)print("skill:",skill)print("year:",year) staff("lemi",22,"python_devops")關鍵參數正常情況下,給函數傳參數要按順序,不想按順序就可以用關鍵參數,只需指定參數名即可(指定了參數名的參數就叫關鍵參數),但記住一個要求就是,關鍵參數必須放在位置參數(以位置順序確定對應關系的參數)之后
def staff(name,age,skill,year=2018): print('staff info'.center(20,'-')) print("name:",name) print("age:",age) print("skill:",skill) print("year:",year)staff("lemi",skill="python_devops",22) # 不可以 staff("kevin",skill="linux",age=22) #可以這樣 staff("walk",25,"linux",age=22) #不可以,相當于兩次賦值 # 總結:不想按位置參數,一一對應的去傳值, # 就使用關鍵參數(參數名=值),但得只能在位置參數后面, # 相當于,你不想排隊一個個進,想按名進去, # 那你就只能等到前面排隊的進完再進,不然混亂(報錯)非固定參數
若你的函數在定義時不確定用戶想傳入多少個參數,就可以使用非固定參數# *args 會把多傳入的參數變成一個元組形式(args也可以其他形式命名,相當于形參)# args,如果沒傳值,就為空 ()
def staff(name,age,*args): print(name,age,args) staff('lemi',22,'python','CQ') # 輸出 # lemi 22 ('python', 'CQ')當*args在其他形參前面時會截胡,傳遞參數時,他后面的參數用關鍵參數可以解決def staff(name,*args,age): passstaff(‘lemi’,’python’,’linux’,age=22)staff(‘lemi’,*[‘python’,’linux’],age=22) 解包,傳給形參args
# *kwargs 會把多傳入的參數(key-value型)變成一個dict形式{}# kwargs,如果沒傳值,就為空 {}
def staff(name,age,*args,**kwargs): print(name,age,args,kwargs) staff('lemi',22,'linux','web',skill='python',place='CQ') # 輸出 #lemi 22 ('linux', 'web') {'skill': 'python', 'place': 'CQ'}staff('lemi',22,'linux','web',**{’skill’:'python',’place’:'CQ'}) 效果跟上面一樣返回值
函數外部的代碼要想獲取函數的執行結果,就可以在函數里用return語句把結果返回
def staff(name,age,skill,year=2018): print('staff info'.center(20,'-'))print("name:",name)print("age:",age)print("skill:",skill)print("year:",year)if age>22:return Falseelse:return True interview = staff("lemi",22,"python_devops") if interview:print(interview)print('面試成功') else:print('have to improve')output: -----staff info----- name: lemi age: 22 skill: python_devops year: 2018 面試成功 True View Code注意
函數在執行過程中只要遇到return語句,就會停止執行并返回結果,也可以理解為 return 語句代表著函數的結束如果未在函數中指定return,那這個函數的返回值為None函數,只能返回一個值
全局與局部變量
status = 'poor man' def work(status):print('before learn python:',status)status = 'Charming male'print('after change:',status)work(status)print('看看外面status改變了嗎?',status)output: before learn python: poor man after change: Charming male 看看status改變了嗎? poor man不用傳name 值到函數里,也可以在函數里調用外面的變量 # 局部函數可以調用全局變量,但是不能修改 status = 'poor man' def work():status = 'Charming male'print('after change:',status) work() print('看看外面status改變了嗎?',status) output: after change: Charming male 看看外面status改變了嗎? poor man View Code1.在函數中定義的變量稱為局部變量,在程序的一開始定義的變量稱為全局變量。2.全局變量作用域是整個程序,局部變量作用域是定義該變量的函數。3.當全局變量與局部變量同名時,在定義局部變量的函數內,局部變量起作用;在其它地方全局變量起作用。
修改全局變量
status = 'poor man' def work(): global status status = 'Charming male' print('after change:',status) work() print('看看外面status改變了嗎?',status) output after change: Charming male 看看外面status改變了嗎? Charming male View Codeglobal status的作用就是要在函數里聲明status是全局變量,最上面的status='poor man'即使不寫,程序最后面的print也可以打印status
變量是列表時, 當修改的是列表時,可以刪除元素,修改元素skill = ['linux','python','html'] def change_skill():skill = ['linux','python']print(skill) #此處不能修改 change_skill() print(skill)['linux', 'python'] ['linux', 'python', 'html']------------------skill = ['linux','python','html'] def change_skill():skill[2] = 'hadoop'skill.remove('linux')print('inside',skill) #這里可以該,改的是元素,并不是列表對象#因為在內存里,列表對象整體是一個地址,元素又是另一個地址 change_skill() print('outside',skill)inside ['python', 'hadoop'] outside ['python', 'hadoop'] View Code作用域
作用域(scope),程序設計概念,通常來說,一段程序代碼中所用到的名字并不總是有效/可用的,而限定這個名字的可用性的代碼范圍就是這個名字的作用域。python中函數就是一個作用域,局部變量放置在其作用域中。代碼定義完,作用域已經生成,無論在任何地方調用,作用域鏈向上查找
age = 21 def func1():age = 22def func2():print(age)return func2 val = func1() print(val) val()output <function func1.<locals>.func2 at 0x000002AB58965BF8> 22 View Code嵌套函數
name = 'bird kevin' def work():name = 'common staff'def work_1():name = 'outstanding staff'print('level 3',name)work_1()print('level 2',name) work() print('level now',name)OUTPUT level 3 outstanding staff level 2 common staff level now bird kevin # 最外層不能調用work_1()里層函數#小游戲 age = 19 def func1():global agedef func2():print(age)age = 73func2() func1() print(age) #output>>> 73 73age = 19 def func1():def func2():print(age)func2()age = 73func1() print(age) #會報錯,不知道找哪一個 View Code?
匿名函數
匿名函數就是不需要顯式的指定函數名
#a = lambda x,y:x*y print(a(1,2)) lambda 不能有復雜的邏輯。可以三元運算res = map(lambda x:x**2,[1,5,7,4,8]) for i in res: print(i) 輸出1 25 49 16 64 節省代碼高階函數
變量可以指向函數,函數的參數能接收變量,那么一個函數就可以接收另一個函數作為參數,這種函數就稱之為高階函數。
def add(x,y,f):return f(x) + f(y) res = add(3,-6,abs) print(res)只需滿足以下任意一個條件,即是高階函數
1.接受一個或多個函數作為輸入
2.return 返回另外一個函數
遞歸
在函數內部,可以調用其他函數。如果一個函數在內部調用自身本身,這個函數就是遞歸函數
def fac(n):if n == 1:return 1else:return n *fac(n-1) print(fac(3))def calc(n):v = int(n/2)print(v)if v > 0:calc(v)print(n)calc(10)output5 2 1 0 1 2 5 10先一層層進去,再往外走 View Code遞歸特性:
1.必須有一個明確的結束條件
2.每次進入更深一層遞歸時,問題規模相比上次遞歸都應有所減少
3.遞歸效率不高,遞歸層次過多會導致棧溢出(在計算機中,函數調用是通過棧(stack)這種數據結構實現的,每當進入一個函數調用,棧就會加一層棧幀,每當函數返回,棧就會減一層棧幀。由于棧的大小不是無限的,所以,遞歸調用的次數過多,會導致棧溢出)
堆棧掃盲
尾遞歸,調用下一層的時候就退出了 def cal(n):print(n)return cal(n+1) cal(1) 在python并沒有優化 View Code內置函數
內置參數詳解
>>> min([2,3,4]) #返回數字序列最小值2 >>> max([2,3,4]) # 返回數字序列最大值4>>> help(all) Help on built-in function all in module builtins: all(iterable, /)Return True if bool(x) is True for all values x in the iterable.If the iterable is empty, return True.>>> a = [1,2,3] >>> all(a) True >>> a.append(0) >>> all(a) False >>> a.append([]) >>> all(a) False >>> all([]) True>>>help(any) Help on built-in function any in module builtins:any(iterable, /)Return True if bool(x) is True for any x in the iterable.If the iterable is empty, return False.dir 打印當前下變量>>> help(hex)Help on built-in function hex in module builtins:hex(number, /)Return the hexadecimal representation of an integer.>>> hex(12648430)'0xc0ffee'>>> 10//3 3 >>> divmod(10,3) (3, 1) >>> sorted([22,31,13,3,14,1,34,3]) [1, 3, 3, 13, 14, 22, 31, 34] >>> d = {} >>> for i in range(20):d[i] = i-2>>> d {0: -2, 1: -1, 2: 0, 3: 1, 4: 2, 5: 3, 6: 4, 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: 12, 15: 13, 16: 14, 17: 15, 18: 16, 19: 17} >>> sorted(d) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19] >>> d.items <built-in method items of dict object at 0x0000023C083AF5E8> >>> d.items() dict_items([(0, -2), (1, -1), (2, 0), (3, 1), (4, 2), (5, 3), (6, 4), (7, 5), (8, 6), (9, 7), (10, 8), (11, 9), (12, 10), (13, 11), (14, 12), (15, 13), (16, 14), (17, 15), (18, 16), (19, 17)]) >>> sorted(d.items(),key) Traceback (most recent call last):File "<pyshell#11>", line 1, in <module>sorted(d.items(),key) NameError: name 'key' is not defined >>> sorted(d.items(),key=lambda x:x[1]) [(0, -2), (1, -1), (2, 0), (3, 1), (4, 2), (5, 3), (6, 4), (7, 5), (8, 6), (9, 7), (10, 8), (11, 9), (12, 10), (13, 11), (14, 12), (15, 13), (16, 14), (17, 15), (18, 16), (19, 17)] >>> sorted(d.items(),key=lambda x:x[1],reverse = True) [(19, 17), (18, 16), (17, 15), (16, 14), (15, 13), (14, 12), (13, 11), (12, 10), (11, 9), (10, 8), (9, 7), (8, 6), (7, 5), (6, 4), (5, 3), (4, 2), (3, 1), (2, 0), (1, -1), (0, -2)] >>> ascii('n') "'n'" >>> ascii('你') "'\\u4f60'" >>> oct(10) '0o12' >>> bin(10) '0b1010' >>> help(eval) Help on built-in function eval in module builtins:eval(source, globals=None, locals=None, /)Evaluate the given source in the context of globals and locals.The source may be a string representing a Python expressionor a code object as returned by compile().The globals must be a dictionary and locals can be any mapping,defaulting to the current globals and locals.If only globals is given, locals defaults to it.>>> eval('1+7') 8 >>> eval('print('hello world')') SyntaxError: invalid syntax >>> eval('print("hello world")') hello world >>> code = ''' if 5 > 4:print('ok') else:print('fail')''' >>> eval(code) Traceback (most recent call last):File "<pyshell#27>", line 1, in <module>eval(code)File "<string>", line 2if 5 > 4:^ SyntaxError: invalid syntax >>> 只能處理簡單單行代碼 Traceback (most recent call last):File "<pyshell#28>", line 1, in <module>只能處理簡單單行代碼 NameError: name '只能處理簡單單行代碼' is not defined >>> exec(code) ok >>> help(exec) Help on built-in function exec in module builtins:exec(source, globals=None, locals=None, /)Execute the given source in the context of globals and locals.The source may be a string representing one or more Python statementsor a code object as returned by compile().The globals must be a dictionary and locals can be any mapping,defaulting to the current globals and locals.If only globals is given, locals defaults to it.>>> res = eval('1+3+4') >>> res1 = exec('1+3+4') >>> print('res',res,res1) res 8 None >>> exec可以執行多行但拿不到返回值 KeyboardInterrupt >>> eval執行單行可以拿到返回值 KeyboardInterrupt >>> ord('a') 97 >>> chr('98') Traceback (most recent call last):File "<pyshell#35>", line 1, in <module>chr('98') TypeError: an integer is required (got type str) >>> chr(98) 'b' >>> s = '元貞' >>> s[0] '元' >>> s.encode('utf-8') b'\xe5\x85\x83\xe8\xb4\x9e' >>> s1 = bytearray(s) Traceback (most recent call last):File "<pyshell#40>", line 1, in <module>s1 = bytearray(s) TypeError: string argument without an encoding >>> s1 = bytearray(s.encode (utf-8)) Traceback (most recent call last):File "<pyshell#41>", line 1, in <module>s1 = bytearray(s.encode (utf-8)) NameError: name 'utf' is not defined >>> s1 = bytearray(s.encode ('utf-8')) >>> s1[0] = 'a' Traceback (most recent call last):File "<pyshell#43>", line 1, in <module>s1[0] = 'a' TypeError: an integer is required >>> s1[0] = 65 >>> s '元貞' >>> s1 bytearray(b'A\x85\x83\xe8\xb4\x9e') >>> s1[4] 180 >>> id(s[0]) 2456860022384 >>> 源地址修改 KeyboardInterrupt >>> map(lambda x:x*x,[1,2,3]) <map object at 0x0000023C0842C908> >>> list(map(lambda x:x*x,[1,2,3])) [1, 4, 9] >>> list(map(lambda x:x<3,[1,2,3])) [True, True, False] >>> list(filter(lambda x:x<3,[1,2,3])) [1, 2] >>> import functools >>> functools.reduce <built-in function reduce> >>> bytes('34') Traceback (most recent call last):File "<pyshell#55>", line 1, in <module>bytes('34') TypeError: string argument without an encoding >>> bytes('34)SyntaxError: EOL while scanning string literal >>> bytes(34)b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' >>> bytes('你好')Traceback (most recent call last):File "<pyshell#58>", line 1, in <module>bytes('你好') TypeError: string argument without an encoding >>> bytes(你好)Traceback (most recent call last):File "<pyshell#59>", line 1, in <module>bytes(你好) NameError: name '你好' is not defined >>> print('python','linux',sep='->')python->linux >>> print('python','linux',end='->')python linux-> >>> print('python','linux')python linux >>> print('python','linux',end='')python linux >>>msg = 'linux is lady ' f = open('skill.txt','w') print(msg,'python is yong woman',sep='|',end="",file=f) print(msg,'python is yong woman',sep='|',end="",file=f)>>> def f():pass>>> a = [1,2,3]>>> callable(f)True >>> callable(a)False>>> s = {1,2,3,4}>>> s.discard(2)>>> s{1, 3, 4} >>> s = frozenset(s)>>> sfrozenset({1, 3, 4}) >>> >>> >>> s.discard(3)Traceback (most recent call last):File "<pyshell#77>", line 1, in <module>s.discard(3) AttributeError: 'frozenset' object has no attribute 'discard' >>> s.remove(2)Traceback (most recent call last):File "<pyshell#78>", line 1, in <module>s.remove(2) AttributeError: 'frozenset' object has no attribute 'remove'打印變量名和對應的值 >>> vars(){'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'd': {0: -2, 1: -1, 2: 0, 3: 1, 4: 2, 5: 3, 6: 4, 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: 12, 15: 13, 16: 14, 17: 15, 18: 16, 19: 17}, 'i': 19, 'code': "\nif 5 > 4:\n print('ok')\nelse:\n print('fail')", 'res': 8, 'res1': None, 's': frozenset({1, 3, 4}), 's1': bytearray(b'A\x85\x83\xe8\xb4\x9e'), 'functools': <module 'functools' from 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\functools.py'>, 'f': <function f at 0x0000023C08464400>, 'a': [1, 2, 3]}>>> def f():n = 3print(locals())>>> f(){'n': 3} >>> globals(){'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'd': {0: -2, 1: -1, 2: 0, 3: 1, 4: 2, 5: 3, 6: 4, 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: 12, 15: 13, 16: 14, 17: 15, 18: 16, 19: 17}, 'i': 19, 'code': "\nif 5 > 4:\n print('ok')\nelse:\n print('fail')", 'res': 8, 'res1': None, 's': frozenset({1, 3, 4}), 's1': bytearray(b'A\x85\x83\xe8\xb4\x9e'), 'functools': <module 'functools' from 'C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python36\\lib\\functools.py'>, 'f': <function f at 0x0000023C084646A8>, 'a': [1, 2, 3]} >>>>>> a[1, 2, 3] >>> repr(a)'[1, 2, 3]'>>> a[1, 2, 3] >>> b = [6,7,8]>>> zip(a,b)()Traceback (most recent call last):File "<pyshell#96>", line 1, in <module>zip(a,b)() TypeError: 'zip' object is not callable >>> list(zip(a,b))[(1, 6), (2, 7), (3, 8)] >>> View Code總結
- 上一篇: S3 exercise -- 文件操作函
- 下一篇: py-opp 类(class)