Python自學筆記-第8章高級程序設計技術(1)

本節介紹一些以前語法的高級使用,能夠是咱們的程序看起來更爲優雅和高效。python

 

1.過程性程序設計

 

1.1.使用字典進行分支

若是遇到大量含有if和elif的分支判斷中,按照傳統的寫法無疑會下降程序邏輯的可讀性,此時可使用字典方式替換if else的使用。express

 

如下示例進行說明:安全

In [3]:
a = 10
b = 8
strs = input("輸入你的操做:")
if strs == '+':
    print(a+b)
elif strs == '-':
    print(a-b)
elif strs == '*':
    print(a*b)
else:
    print(a/b)
 
輸入你的操做:+
18
 

能夠轉化爲:app

In [4]:
a = 10
b = 8
strs = input("輸入你的操做:")
actions = {'+':a+b,'-':a-b,'*':a*b,'/':a/b}
print(actions[strs])
 
輸入你的操做:+
18
 

1.2.生成器表達式與函數

 

生成器提供了一種執行「惰性」評估的方法,意味着只有在實際須要的時候才計算值,這比一次性計算一個很大的列表要更加有效。有效的生成器能夠生成咱們所須要數量的值--而沒有上限函數

 
  • 生成器表達式的語法以下:
    (expression for item in iterable)
    (expression for item in iterable if condition)
In [5]:
for t in (x for x in range(10) if x%2==0):
    print(t)
 
0
2
4
6
8
 
  • 生成器函數的語法以下:
In [11]:
def getNum(num=1):
    num = 1
    while True:
        yield num
        num +=1
In [12]:
getNum()
Out[12]:
<generator object getNum at 0x00000214B6597D58>
In [13]:
for t in getNum():
    if t > 5:
        break
    print(t)
 
1
2
3
4
5
 
  • 使用send方法改進的生成器函數爲:
In [16]:
def getNum1(num=1):
    num = 1
    while True:
        recived = yield num
        if recived is None:
            num += 1
        else:
            num = recived + 10
In [17]:
result = []
cnum = getNum1(2)
while len(result)<5:
    x = next(cnum)
    if x==4:
        x = cnum.send(7)
    result.append(x)
In [18]:
print(result)
 
[1, 2, 3, 17, 18]
 

1.3.動態代碼執行與動態導入

 

動態代碼執行便是讓用戶本身輸入代碼並讓Python執行,此種方法即容許Python程序執行任意代碼必然會帶來很大的安全風險,故而須要謹慎使用。ui

 

另外經過動態執行,能夠爲程序增長和擴展動態功能。spa

 

1.3.1.eval()函數

 

計算指定表達式的值。也就是說它要執行的python代碼只能是單個表達式(注意eval不支持任何形式的賦值操做),而不能是複雜的代碼邏輯。其語法格式以下:設計

eval(source, globals=None, locals=None)
 

參數說明:code

  • source:必選參數,能夠是字符串,也能夠是一個任意的code(代碼)對象實例(能夠經過complie函數建立)。若是它是一個字符串,它會被看成一個(使用globals和locals參數做爲全局和本地命名空間的)python表達式進行分析和解釋。
  • globals:可選參數,表示全局命名空間(存放全局變量),若是被提供,則必須是一個字典對象。
  • locals:可選參數,表示全局命名空間(存放局部變量),若是被提供,能夠是任何映射對象。若是參數被忽略,那麼它將會取與globals相同的值。 若是globals與locals都被忽略,那麼它們將取eval()函數被調用環境下的全局命名空間和局部命名空間。
 

返回值:對象

  • 若是source是一個code對象,且建立該code對象時,complie函數的mode參數是‘exec’,那麼eval()函數的返回值是None;
  • 不然,若是source是一個輸出語句,如print(),則eval()返回結果爲None;
  • 不然,source表達式的結果就是eval()函數的返回值
In [23]:
eval(input('請您輸入要執行的腳本:'))
 
請您輸入要執行的腳本:print([x for x in range(5)])
[0, 1, 2, 3, 4]
 

1.3.2.exec()函數

動態執行python代碼。也就是說exec能夠執行復雜的python代碼,而不像eval函數那樣只能計算一個表達式的值。

exec(source, globals=None, locals=None)
 

參數說明:

  • source:必選參數,表示須要被指定的python代碼。它必須是字符串或code對象。若是source是一個字符串,該字符串會先被解析爲一組python語句,而後執行。若是source是一個code對象,那麼它只是被簡單的執行。
  • globals:可選參數,這個參數管控的是一個全局的命名空間,即 expression 可使用全局命名空間中的函數。若是隻是提供了 globals 參數,而沒有提供自定義的 __builtins__,則系統會將當前環境中的 __builtins__ 複製到本身提供的 globals 中,而後纔會進行計算;若是連 globals 這個參數都沒有被提供,則使用 Python 的全局命名空間。
  • locals:可選參數,這個參數管控的是一個局部的命名空間,和 globals 相似,當它和 globals 中有重複或衝突時,以 locals 的爲準。若是 locals 沒有被提供,則默認爲 globals。
 

返回值:

  • exec函數的返回值永遠爲None。
In [27]:
import math
code = """
def area_of_sphere(r):
     print(4*math.pi*r**2)
"""

context = {}
context['math']=math
exec(code,context)
In [28]:
area_of_sphere = context['area_of_sphere']
area_of_sphere(5)
 
314.1592653589793
 

globals參數便可做爲exec執行函數中須要獲取參數或模塊的來源(如:math),也能夠做爲外部想獲取exec執行函數的字典(如:area_of_sphere)

 

1.3.3.complie()函數

compile() 函數將一個字符串編譯爲字節代碼。其語法格式

compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)
 

參數說明:

  • source:字符串或AST對象,表示須要進行編譯的python代碼
  • filename:指定須要編譯的代碼文件,若是不是文件讀取代碼則傳遞一些可辨認的值。
  • mode:用於標識必須當作那類表明來編譯;若是source是由一個代碼語句序列組成,則指定mode=‘exec’,若是source由單個表達式組成,則指定mode=‘eval’;若是source是由一個單獨的交互式語句組成,則指定modo=‘single’。必需要制定,否則確定會報錯。
In [46]:
code = """
import math
def area_of_sphere(r):
     print(4*math.pi*r**2)
"""
c = compile(code,'','exec')
c
Out[46]:
<code object <module> at 0x00000214B6662C90, file "", line 2>
In [50]:
context = {}
exec(c,context)
context['area_of_sphere'](5)
 
314.1592653589793
In [51]:
exec(c)
c1 = globals()['area_of_sphere']
c1(5)
 
314.1592653589793

更多文章,請關注:
 

相關文章
相關標籤/搜索