Build-in Functions

execfile() (Python2)

简介

execfile()是Python2的一个内建函数,Python3中不再支持。该函数可以执行文件中的Python语句。目前对该函数还不是特别理解,主要的几个相对有用的资料如下:

语法

execfile (filename[, globals[, locals]])

参数

  • filename -- 必填,需要执行的文件
  • globals -- 可选,以字典形式传入,提供给执行此文件的全局名空间
  • locals -- 可选,以字典形式传入,提供给执行此文件的局部名空间

说明

首先要注意这里的globalslocals是参数,Python还有两个相像的内建函数分别是globals()locals(),分别返回调用该函数处的全局变量字典和局部变量字典。

globalslocals参数可以分别传入两个字典,主要有两个作用,一是提供运行filename可以访问的名空间,二是记录filename文件内的名空间。

如果不提供可选参数,则默认该文件, filename, 执行过程中能访问调用execfile()处的全局和局部名空间,即默认传入globals()locals(),不过注意locals()生成的局部名空间字典无法修改,只能访问。当然可以通过传入namespace = {}的方式使filename执行时无法访问外部的名空间,即execfile('example.py', namespace),此时namespace没有提供filename执行可以访问的外部名空间,但字典namespace可以记录filename内的名空间。

返回值

None

示例

不提供可选参数

此时默认该文件, filename, 执行过程中能访问调用execfile()处的全局和局部名空间。

假设filename为simple_function.py,其内容如下:

import math

def even_numbers_only(thelist):
    '''
    Returns a list of even numbers in thelist
    '''
    return [x for x in thelist if x%2 == 0]

def is_perfect_square(x):
    '''
    Returns True if x is a perfect square, False otherwise
    '''
    thesqrt = int(math.sqrt(x))
    return thesqrt * thesqrt == x

然后可以用execfile()运行该文件,看看其对名空间的改变:

~$ python
Python 2.7.3 (default, Sep 26 2012, 21:51:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> math
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'math' is not defined
>>> execfile('simple_functions.py')
>>> math
<module 'math' (built-in)>
>>> is_perfect_square(144)
True
>>> even_numbers_only([0,5,8,12,55,48])
[0, 8, 12, 48]

传入空字典到globals参数

这样可以阻止execfile()改变调用它的环境的名空间,同时空字典可以记录filename中的名空间。

~$ python
Python 2.7.3 (default, Sep 26 2012, 21:51:14)
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> namespace = {}
>>> execfile('simple_functions.py', namespace)
>>> namespace['is_perfect_square'](144)
True
>>> is_perfect_square
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'is_perfect_square' is not defined

locals()生成的名空间不可修改

主要是对locals()还不是很理解,但记住其不能通过exfile()修改就可以了。假设simeple_file.py内容如下:

x = 15

然后可以看到exexfile()无法修改locals()

>>> # Attempting to alter a variable local to a function
>>> def f():
...     x = -1
...     execfile('simple_file.py')
...     return(x)
...
>>> f()
-1
>>> # We try again, passing globals() in as globals argument
>>> def f():
...     x = -1
...     execfile('simple_file.py', globals())
...     return(x)
...
>>> f()
-1
>>> # We try again, passing both globals and locals
>>> def f():
...     x = -1
...     execfile('simple_file.py', globals(), locals())
...     return(x)
...
>>> f()
-1
>>> # It still doesn't work!

super() (Python2)

简介

一个常见误区是super()是调用父类,事实上其本质是这样的:

def super(cls, inst):
    mro = inst.__class__.mro()
    return mro[mro.index(cls) + 1]

两个参数 clsinst 分别做了两件事:

  • inst 负责生成 MROlist
  • 通过 cls 定位当前 MRO 中的 index, 并返回 mro[index + 1] 这两件事才是 super() 的实质。 MRO 全称 Method Resolution Order,它代表了类继承的顺序。

示例

class Root(object):
    def __init__(self):
        print("this is Root")

class B(Root):
    def __init__(self):
        print("enter B")
        # print(self)  # this will print <__main__.D object at 0x...>
        super(B, self).__init__()
        print("leave B")

class C(Root):
    def __init__(self):
        print("enter C")
        super(C, self).__init__()
        print("leave C")

class D(B, C):
    pass

d = D()
print(d.__class__.__mro__)

结果

enter B
enter C
this is Root
leave C
leave B
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.Root'>, <type 'object'>)

说明:

  • 首先实例化D,即D.__init__(d),但类D没有该方法,就会在其MRO列表中向后搜索该方法调用,即B.__init__(d)
  • 打印出enter B,接着调用super(B, d).__init__(),对照上面可知super(B, d)即为C,以此类推。

在 MRO 中,基类永远出现在派生类后面,如果有多个基类,基类的相对顺序保持不变。另外,super()MRO ,都是针对 new-style class的。

zip() (Python)

语法

zip(iterable,...)

参数

  • iterable--迭代体

返回值

返回一个列表,列表中每个元素是一个元组,元组中每个元素分别来自每个迭代体,每个元组长度相等,等于迭代体个数,列表的长度等于最小的迭代体长度。

示例

In [1]: x = [1, 2, 3]
In [2]: y = [4, 5, 6]
In [3]: z = [7, 8, 9]
In [4]: p = [10, 11]
In [5]: s = [x, y, z]

In [6]: s
Out[6]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [7]: print zip(x)
[(1,), (2,), (3,)]

In [8]: print zip(x, p)
[(1, 10), (2, 11)]

In [9]: print zip(x, y, z)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]

In [10]: print zip(*s)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]

示例中最后一个表达式涉及到的是参数解包,以后需要对其总结一下。

results matching ""

    No results matching ""