函數詳解day04
目錄
1.函數對象:函數是第一類對象,即函數可以當做數據被傳遞... 1
2.函數的嵌套調用:在一個函數內部調用其他函數... 1
3.函數的嵌套定義:... 1
4.名稱空間與作用域... 1
5.閉包函數:內部函數包含對外部作用而非全局作用域的引用,該內部函數就是閉包函數 2
1.函數對象:函數是第一類對象,即函數可以當做數據被傳遞
1.可以被引用
2.可以當做參數傳遞
3.返回值可以是函數
4.可以當做容器類型的元素
2.函數的嵌套調用:在一個函數內部調用其他函數
3.函數的嵌套定義:
def f1():
def f2():
print(‘f2‘)
def f3():
print(‘f3‘)
f1()
執行結果:什麽都沒有,因為只是定義了,沒有調用f2
def f1():
def f2():
print(‘f2‘)
def f3():
print(‘f3‘)
f3()
f2()
f1()
輸出結果:f2,f3
4.名稱空間與作用域
全局作用域:內置名稱空間,全局名稱空間
局部作用:局部名稱空間
變量查找順序:局部->全局->內置
x = 1000
def func(y):
x=2
print(locals())#打印局部變量
print(globals())#打印全部變量
func(1)
輸出結果:
{‘x‘: 2, ‘y‘: 1}
{‘__loader__‘: <_frozen_importlib_external.SourceFileLoader object at 0x0000000000657B38>, ‘__spec__‘: None, ‘__name__‘: ‘__main__‘, ‘__builtins__‘: <module ‘builtins‘ (built-in)>, ‘__doc__‘: None, ‘__package__‘: None, ‘x‘: 1000, ‘__file__‘: ‘D:/kinggsoft/python_file/day04/day04.py‘, ‘__cached__‘: None, ‘func‘: <function func at 0x0000000000711400>}
5.閉包函數:內部函數包含對外部作用而非全局作用域的引用,該內部函數就是閉包函數
def f1():
x = 1#外部非全局變量
def f2():
print(x)
return f2
res = f1()#返回f2地址
res()
函數外面包了一層函數,用來控制變量作用域
6.裝飾器:
usr_info={‘username‘:None,‘state‘:False}
def auth(a):
def auth2(func):
def wrapper(*args,**kwargs):
if args[0] ==‘dodo‘ and args[1] == ‘111‘:
func(*args,**kwargs)
usr_info[‘username‘]=args[0]
usr_info[‘state‘]=True
if a == ‘dodo‘:
print(‘supper manger‘)
elif a:
print(‘ussall‘)
return wrapper
return auth2
@auth(adapt)#welcom=auth(welcome)
def welcome(name,pwd):
print(‘welcome,%s‘ %(name))
while True:
name =input(‘name:‘)
pwd = input(‘pwd‘)
a=welcome(name, pwd)
if a ==1:
break
6.裝飾器:裝飾別人的工具,修飾->添加功能,工具->函數
裝飾器本身可能是任何可調用對象,函數(還有類)
被裝飾對象也可能是任意可調用對象
為什麽要用裝飾器:對修改是封閉的,對擴張是開放的
裝飾器就是為了在不修改源代碼和函數調用方式的前提下,為其添加新功能
import time
def f(func):
def timmer(*args):
start = time.time()
func(*args)
end = time.time()
print(‘time:%s‘ %(end-start))
return timmer
@f#hello=timmer(hello)
def hello(name):
time.sleep(3)
print(‘hello!%s‘ %(name))
hello(‘egon’)
輸出結果:
hello!egon
time:3.000171422958374
7.有參裝飾器
#有參裝飾器
def auth(driver):
def login(func):
def wrapper(*args,**kwargs):
if driver == ‘file‘:
if args[0]==‘dodo‘ and args[1] ==‘123‘:
a=func(*args,**kwargs)
return 1
else:
print(‘請輸入正確的賬號密碼!‘)
else:
print(‘不識別的驅動‘)
return wrapper
return login
@auth(‘file‘)
def welcome(name,pwd):
print("*************welcome*************")
print("*************%s*************" %name)
return 1
while True:
name = input(‘name:‘)
pwd = input(‘pwd:‘)
a=welcome(name,pwd)
if a == 1:
break
8.多層裝飾器嵌套
import time
def timmer(func):
def wrapper(*args,**kwargs):
start=time.time()
time.sleep(3)
func(*args,**kwargs)
end=time.time()
print(‘time:%s‘ %(end-start))
return 1
return wrapper
def login(func):#login = auth(login)
def wrapper(*args,**kwargs):
start = time.time()
time.sleep(3)
if args[0]==‘dodo‘ and args[1] ==‘123‘:
a=func(*args,**kwargs)
end = time.time()
print(‘logintime:%s‘ % (end - start))
return 1
else:
print(‘請輸入正確的賬號密碼!‘)
return wrapper
@timmer
@login
def welcome(name,pwd,driver):
print("*************welcome*************")
print("*************%s*************" %name)
return 1
while True:
name = input(‘name:‘)
pwd = input(‘pwd:‘)
a=welcome(name,pwd,‘file‘)
if a == 1:
break
輸出結果:
name:dodo
pwd:123
*************welcome*************
*************dodo*************
logintime:3.000171661376953
time:6.000343322753906
9.叠代器
重復的過程稱為叠代,每次叠代都是下次叠代的初始值
為什麽要用叠代器:對於沒有索引的數據類型,必須提供一種不依賴於索引的叠代方式
只要數據類型下有__iter__()方法就是可叠代的,執行iter方法得到的結果就是叠代器
i=[1,2,3,4].__iter__()
print(i)
print(i.__next__())
輸出結果:
<list_iterator object at 0x0000000000A70278>
1
通過next方法遍歷
對字典的遍歷,只能取到key,取不到val
i={‘bb‘:2,‘aa‘:4}.__iter__()
print(i)
print(i.__next__())
輸出結果
<dict_keyiterator object at 0x00000000011C5408>
bb
用叠代器遍歷字典
dic ={‘bb‘:2,‘aa‘:4}
i=dic.__iter__()
print(i)
while True:
val=i.__next__()
print(dic[val])
輸出結果
Traceback (most recent call last):
File "D:/kinggsoft/python_file/day04/day04.py", line 187, in <module>
val=i.__next__()
StopIteration
<dict_keyiterator object at 0x0000000001195408>
4
2
如何判斷一個對象是可叠代的對象,還是叠代器對象
from collections import Iterable,Iterator
‘abc‘.__iter__()
[].__iter__()
{}.__iter__()
{‘a‘:1}.__iter__()
(1,).__iter__()
with open(‘ceshi.py‘) as f :
f.__iter__()
print(isinstance(‘aa‘,Iterable))
print(isinstance(‘aa‘,Iterator))
輸出結果:
True
False
可叠代對象只有iter方法,
叠代器有next和iter方法
叠代協議:
對象有__next__方法
對象有__iter__對於叠代器對象來說,叠代器執行__iter__方法得到的還是叠代器本身,
for循環,enumerate也是叠代器
#for循環
dic = {‘name‘:‘lili‘,‘age‘:18}
for i in dic:#k=iter(dic) i=next(k)
print(i)
相當於
i=iter(dic)
while True:
try:
k=next(i)
print(k)
except StopIteration:
break
叠代器的有點和缺點
有點
- 提供了不依賴下標的叠代方式
- 就叠代器本身來說更節省內存
缺點
- 沒有序列不靈活
- 無法獲取長度
10.生成器
生成器函數:只要函數體包含yeild關鍵字,該函數就叫做生成器函數
吧函數變成了叠代器
ps:只要函數中有yield,就加括號不會執行函數,而是把函數變成叠代器
yield
#yeild
def foo():
yield 1
yield 2
yield 3
g=foo()
print(g)
print(next(g))
print(next(g))
print(next(g))
輸出結果:
1
2
3
def foo():
print(‘one‘)
yield 1
print(‘two‘)
yield 2
print(‘three‘)
yield 3
g=foo()
print(g)
res=print(next(g))
輸出結果
<generator object foo at 0x00000000006A1BF8>
one
1
yield:功能
- 相當於為函數封裝好iter和next方法
- return 只能返回一次值
yield返回多次值
#tail -f |grep ‘python‘
def tail():
import time
with open(‘與鐵林‘,‘r+‘) as f:
f.seek(0, 2) # 跳到文件末尾
while True:
line = f.readline()
if line:
if ‘python‘ in line:
yield line
else:
time.sleep(0.2)
a=tail()
print(next(a))
程序執行結果
直到文件有新內容輸入保存為止
內置函數
- abs——絕對值
- all——對所有值進行bool值判斷,如果是返回true
all([1,2,3])=ètrue
- any——只要一個是true就是true,空也是false
- bin——十進制轉為二進制
- hex——十進制轉為十六進制
- oct——十進制轉為八進制
- chr——ASCII轉為字符
- ord——字符轉為ASCII
- complex——復數
- 工廠函數——dict、int、list、str、set
- dir——查看屬性
- divmod(100,3)——打印輸出(33,1)主要是分頁功能
- eval——把字符串裏的內容提取出來執行
cmd=‘print(‘哈哈哈’)’
eval(cmd)
- frozenset——定義不可變集合
- hash——主要做校驗,是一種算法
- 只要校驗內容一致,hash也是一樣的
- 不可逆:不能根據hash值退回原值
- 只要采用hash算法一樣的,不論被校驗的內容多長,hash一樣長
- id——看對象的身份
- is——身份運算符
x=1
y=x
print(id(x),id(y))=è得到的值是一樣的
print(x is y)èTrue
- max——最大值
- pow——pow(10,2,3)è10的平方%3
- reverse——反轉,反轉返回的是一個叠代器,不會影響原值
l=[‘a‘,2,4]
a=reversed(l)
print(a)
print(reversed(l))
print(list(reversed(l)))
print(l)
輸出結果:
<list_reverseiterator object at 0x0000000000820278>
<list_reverseiterator object at 0x0000000000820470>
[4, 2, ‘a‘]
[‘a‘, 2, 4]
超級重點:
l=[‘a‘,2,4]
a=reversed(l)
for i in a:
print(i)
print(reversed(a))
輸出結果:
Traceback (most recent call last):
File "D:/kinggsoft/python_file/day04/day04.py", line 244, in <module>
print(reversed(a))
TypeError: argument to reversed() must be a sequence
4
2
a
因為for已經把叠代器走完
- round——保留小數,默認兩位,四舍五入
- slice——切片
- vars——如果不加參數同locals查看局部變量
- zip——一一對應
s=‘hello‘
l=[1,2,3,4,5,6,7]
z=zip(s,l)è叠代器
print(z)
for i in z:
print(i)
輸出結果:
<zip object at 0x00000000007669C8>
(‘h‘, 1)
(‘e‘, 2)
(‘l‘, 3)
(‘l‘, 4)
(‘o‘, 5)
函數詳解day04