1. 程式人生 > >python3 函數 二

python3 函數 二

域名 oba 開放封閉原則 查找 break python pattern art 作用域

1、函數嵌套

1、1函數嵌套定義 :在一個函數的內部,又定義另外一個函數。

def f1():
x=1
def f2():
print(‘from f2‘)
f2()
f1()

1、2函數的嵌套調用:在調用一個函數的過程中,又調用了其他函數。

def bar():

print(‘from bar‘)

def foo():
print(‘from foo‘)
bar()
foo()

通過函數的嵌套使用,分解成操作減少重復代碼,一次調用。

2、名稱空間與作用域

名稱空間

2、1 名稱空間:存放名字的地方,準確的說名稱空間是存放名字與變量值綁定關系的地方

2、2內置名稱空間:python自帶的名字,在python解釋器啟動時產生,存放一些python內置的名字

2、3全局名稱空間:在執行文件時,存放文件級別定義的名字,Python中頂行寫的。

2、4局部名稱空間:在執行文件的過程中,如果調用了函數,則會產生該函數的名稱空間,用來存放該函數內定義的名字,該名字在函數調用時生效,調用結束後失效

2、5加載順序:內置名稱空間------>全局名稱空間----->局部名稱空間

2、6名字的查找順序:局部名稱空間------>全局名稱空間----->內置名稱空間

作用域,作用的範圍

全局作用域:全局存活,全局有效
局部作用域:局部存活,局部有效

定義在函數內部的變量擁有一個局部作用域,定義在函數外的擁有全局作用域。

局部變量只能在其被聲明的函數內部訪問,而全局變量可以在整個程序範圍內訪問。調用函數時,所有在函數內聲明的變量名稱都將被加入到作用域中。

def f1():

x = 1

y = 2

print(locals())

print(globals())

f1()

print(locals())

print(globals())

print(locals() is globals())

修改全局變量的值

x=1

def f1():

global x

x=2

f1()

print(x)

修改局部變量的值

x = 0
def f1():
x = 1
def f2():
x = 2
def f3():
nonlocal x #改的是函數正上方的值
x = 3
f3()
f2()
f1()

優先掌握:作用域關系,在函數定義時就已經固定 ,於調用位置無關,在調用函數時,必須回到函數原來定義的位置去找作用域關系.

x = 1

def f1():

def f2():

print(x)

return f2 x = 1

def f1():

def f2():

print(x)

return f2

func = f1()

func()

func = f1()

func()

查看作用域:globals(),locals()

global

nonlocal

LEGB 代表名字查找順序: locals -> enclosing function -> globals -> __builtins__

locals 是函數內的名字空間,包括局部變量和形參

enclosing 外部嵌套函數的名字空間(閉包中常見)

globals 全局變量,函數定義所在模塊的名字空間

builtins 內置模塊的名字空間

3、閉包函數

3、1 閉包函數: 定義在函數內部的函數

3、2包含對外部作用域名字的引用,而不是對全局作用域名字的引用,那麽該內部函數就稱為閉包函數

import requests

def deco(url):

def wrapper():

return (requests.get(url).text)

return wrapper

get = deco(‘https://www.baidu.com‘)

print(get())

閉包的意義:返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得,該函數無論在何處調用,優先使用自己外層包裹的作用域

4、裝飾器

開放封閉原則:對拓展是開放的,對修改是封閉的

裝飾器:裝飾他人的工具,裝飾的目的是為他人添加新功能

裝飾器本身是任意可調用對象,被裝飾的對象本身也可以是任意可調用的對象

裝飾器遵循的原則:1、不修改被裝飾對象的源代碼

         2、不修改被調用對象的調用方式

裝飾器的目的:在遵循1和2原則的前提下,為其他函數添加新功能

@裝飾器名:必須寫在被裝飾對象的正上方,且是單獨一行

示例:

import time

def timmer(func):

def wrapper(*args,**kwargs):

start_time=time.time()

res=func(*args,**kwargs)

stop_time=time.time()

print(‘run time is %s‘ %(stop_time-start_time))

return res

return wrapper

@timmer

def foo():

time.sleep(3)

print(‘from foo‘)

foo()

裝飾器語法:

被裝飾函數的正上方,單獨一行

@deco1

@deco2

@deco3

def foo():

pass

foo=deco1(deco2(deco3(foo)))

裝飾器補充:wraps

from functools import wraps

def deco(func):

@wraps(func) #加在最內層函數正上方

def wrapper(*args,**kwargs):

return func(*args,**kwargs)

return wrapper

@deco

def index():

‘‘‘去你妹的‘‘‘

print(‘from index‘)

print(index.__doc__)

5、叠代器

叠代器:是一個重復的過程,每一次重復,都是基於上一次的結果而來。

s=‘hello‘

l=[‘a‘,‘b‘,‘c‘,‘d‘]

t=(‘a‘,‘b‘,‘c‘,‘d‘)

dic={‘name‘:‘egon‘,‘sex‘:‘m‘,"age":18}

set1={1,2,3}

f=open(‘db.txt‘)

叠代器對象本身也是可叠代對象

l=[‘a‘,‘b‘,‘c‘,‘d‘]

dic={‘name‘:‘egon‘,‘sex‘:‘m‘,"age":18}

iter_l=iter(l)

iter_dic=iter(dic)

while True:

try:

k=next(iter_dic)

print(k,dic[k])

except StopIteration:

break

可叠代對象:

1 有__iter__,執行得到仍然是叠代本身

2 有__next__

叠代器對象的優點

1、提供了一種統一的(不依賴於索引的)叠代方式

2、叠代器本身,比起其他數據類型更省內存

叠代器對象的缺點

1、一次性,只能往後走,不能回退,不如索引取值靈活

2、無法預知什麽時候取值結束,即無法預知長度

判斷可叠代對象與叠代器對象

print(isinstance(s,Iterable)) 判斷s數據類型是否是可叠代對象

print(isinstance(s,Iterator)) 只有文件是叠代器對象

6、生成器

生成器:

在函數內部包含yield關鍵字,那麽該函數執行的結果就是生成器(生成器就是叠代器)

def func():

print(‘first‘)

yield 11111111

print(‘second‘)

yield 2222222

print(‘third‘)

yield 33333333

print(‘fourth‘)

g=func()

print(g)

from collections import Iterator

print(isinstance(g,Iterator))

yield的功能:

1 把函數的結果做生叠代器(以一種優雅的方式封裝好__iter__,__next__)

2 函數暫停與再繼續運行的狀態是由yield,保存當前運行狀態。

def func(n):

while True:

yield n

n+=1

g=func(0)

print(next(g))

def my_range(start,stop):

while True:

if start == stop:

raise StopIteration

else:

yield start

start+=1

g=my_range(1,3)

for i in my_range(1,3):

print(i)

yield與return的比較?

相同:都有返回值的功能

不同:return只能返回一次值,而yield可以返回多次值

import time

def tail(filepath):

with open(filepath, ‘r‘) as f:

f.seek(0, 2)

while True:

line = f.readline()

if line:

yield line

else:

time.sleep(0.2)

def grep(pattern,lines):

for line in lines:

if pattern in line:

print(line,end=‘‘)

grep(‘error‘,tail(‘access.log‘))

7、三元表達式,列表推導式,生成器表達式

三元表達式

x=10

res=x if x > 3 else ‘no‘

print(res)

列表解析

l = [‘egg%s‘%i for i in range(10)]

l=[‘egg%s‘ %i for i in range(10) if i >=5]

print(l)

names = [‘alex_sb‘,‘egon‘,‘wupeiqi_sb‘,‘yuanhao_sb‘]

names_new = [name for name in names if name.endswith(‘sb‘)]

print(names_new)

生成器表達式

g = (‘egg%s‘%i for i in range(10)) # 將中括號變成小括號即為生成器表達式

# 叠代器同一時間在內存中只有一個值

print(g)

print(next(g))

print(next(g))

with open(‘a.txt‘,encoding=‘utf-8‘) as f:

g=(len(line) for line in f)

print(max(g))

python3 函數 二