zoukankan      html  css  js  c++  java
  • pass、del和exec

    有时候什么都不用做。这种情况不多,但一旦遇到,知道可使用pass语句大有裨益。

    >>> pass
    >>>

    这里什么都没有发生。

    对于你不再使用的对象,Python通常会将其删除(因为没有任何变量或数据结构成员指向它)。

    >>> scoundrel = {'age': 42, 'first name': 'Robin', 'last name': 'of Locksley'}
    >>> robin = scoundrel
    >>> scoundrel
    {'age': 42, 'first name': 'Robin', 'last name': 'of Locksley'}
    >>> robin
    {'age': 42, 'first name': 'Robin', 'last name': 'of Locksley'}
    >>> scoundrel = None
    >>> robin
    {'age': 42, 'first name': 'Robin', 'last name': 'of Locksley'}
    >>> robin = None

    最初,robinscoundrel指向同一个字典,因此将None赋给scoundrel后,依然可以通过robin来访问这个字典。但将robin也设置为None之后,这个字典就漂浮在计算机内存中,没有任何名称与之相关联,再也无法获取或使用它了。因此,智慧无穷的Python解释器直接将其删除。这被称为垃圾收集。请注意,在前面

    的代码中,也可将其他任何值(而不是None)赋给两个变量,这样字典也将消失。

    另一种办法是使用del语句。

    >>> x = ["Hello", "world"]
    >>> y = x
    >>> y[1] = "Python"
    >>> x
    ['Hello', 'Python']

    你可能认为通过删除x,也将删除y,但情况并非如此。

    >>> del x
    >>> y
    ['Hello', 'Python']

    这是为什么呢?xy指向同一个列表,但删除xy没有任何影响,因为你只删除名称x,而没有删除列表本身(值)。事实上,在Python中,根本就没有办法删除值,而且你也不需要这样做,因为对于你不再使用的值,Python解释器会立即将其删除。

    hon解释器会立即将其删除。

    有时候,你可能想动态地编写Python代码,并将其作为语句进行执行或作为表达式进行计算。这可能犹如黑暗魔法,一定要小心。execeval现在都是函数,但exec以前是一种语句,而eval与它紧密相关。这就是我在这里讨论它们的原因所在。

    警告 本节介绍如何执行存储在字符串中的Python代码,这样做可能带来严重的安全隐患。如果将部分内容由用户提供的字符串作为代码执行,将无法控制代码的行为。

    函数exec用于将字符串作为Python程序执行。

    函数eval计算用字符串表示的表达式并返回结果。

     exec

     函数exec将字符串作为代码执行。

    >>> exec("print('Hello, world!')")
    Hello, world!

    然而,调用函数exec时只给它提供一个参数绝非好事。在大多数情况下,还应向它传递一个命名空间——用于放置变量的地方;否则代码将污染你的命名空间,即修改你的变量。例如,假设代码使用了名称sqrt,结果将如何呢?

    >>> from math import sqrt
    >>> exec("sqrt = 1")  #变量名被赋值为1,后面调用时会出错
    >> sqrt(4)
    Traceback (most recent call last):
      File "<pyshell#18>", line 1, in ?
        sqrt(4)
    TypeError: object is not callable: 1

    既然如此,为何要将字符串作为代码执行呢?函数exec主要用于动态地创建代码字符串。如果这种字符串来自其他地方(可能是用户),就几乎无法确定它将包含什么内容。因此为了安全起见,要提供一个字典以充当命名空间。

     注意 命名空间(作用域)是个重要的概念,将在下一章深入讨论,但就目前而言,你可将命名空间视为放置变量的地方,类似于一个看不见的字典。因此,当你执行赋值语句x = 1时,将在当前命名空间存储键x和值1。当前命

     名空间通常是全局命名空间(到目前为止,我们使用的大都是全局命名空间),但并非必然如此。

    为此,你添加第二个参数——字典,用作代码字符串的命名空间。

    >>> from math import sqrt
    >>> scope = {}
    >>> exec('sqrt = 1', scope)
    >>> sqrt(4)
    2.0
    >>> scope['sqrt']
    1

    如你所见,可能带来破坏的代码并非覆盖函数sqrt。函数sqrt该怎样还怎样,而通过exec执行赋值语句创建的变量位于scope中。

     请注意,如果你尝试将scope打印出来,将发现它包含很多内容,这是因为自动在其中添加了包含所有内置函数和值的字典__builtins__

    >>> len(scope)
    2
    >>> scope.keys()
    ['sqrt', '__builtins__']

    eval

    eval是一个类似于exec的内置函数。exec执行一系列Python语句,而eval计算用字符串表示的Python表达式的值,并返回结果(exec什么都不返回,因为它本身是条语句)。例如,你可使用如下代码来创建一个Python计算器:

    >>> eval(input("Enter an arithmetic expression: "))
    Enter an arithmetic expression: 6 + 18 * 2
    42

    警告 虽然表达式通常不会给变量重新赋值,但绝对能够这样做,如调用给全局变量重新赋值的函数。因此,将eval用于不可信任的代码并不比使用exec安全。当前,在Python中执行不可信任的代码时,没有安全的办法。

    浅谈作用域

    execeval提供命名空间时,可在使用这个命名空间前在其中添加一些值。

    >>> scope = {}
    >>> scope['x'] = 2
    >>> scope['y'] = 3
    >>> eval('x * y', scope)
    6

    同样,同一个命名空间可用于多次调用execeval

    >>> scope = {}
    >>> exec('x = 2', scope)
    >>> eval('x * x', scope)
    4

    采用这种做法可编写出非常复杂的程序,但你也许不应这样做。

    实际上,可向exec提供两个命名空间:一个全局的和一个局部的。提供的全局命名空间必须是字典,而提供的局部命名空间可以是任何映射。这一点也适用于eval

    小结:

    passdelexeceval:pass语句什么都不做,但适合用作占位符。del语句用于删除变量或数据结构的成员,但不能用于删除值。函数exec用于将字符串作为Python程序执行。函数eval计算用字符串表示的表达式并返回结果。

  • 相关阅读:
    有感于《CommunityServer 2007 beta》版本的发布
    企业内部办公自动化之---预定系统
    企业办公自动化之三--内部网的部分实现
    推荐一个超人气的类似MSN弹出的控件
    如何创建类型FreeTextBox的编辑器
    输出EXCEL文件的通用函数,很实用
    ASP导出Excel数据的四种方法
    常用的一些工具总结
    ASP2DLL工具
    分層排序的SQL
  • 原文地址:https://www.cnblogs.com/iBoundary/p/11241148.html
Copyright © 2011-2022 走看看