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

更多文章,请关注:
 

相关文章
相关标签/搜索