Build-in Functions
execfile()
(Python2)
简介
execfile()
是Python2的一个内建函数,Python3中不再支持。该函数可以执行文件中的Python语句。目前对该函数还不是特别理解,主要的几个相对有用的资料如下:
语法
execfile (filename[, globals[, locals]])
参数
- filename -- 必填,需要执行的文件
- globals -- 可选,以字典形式传入,提供给执行此文件的全局名空间
- locals -- 可选,以字典形式传入,提供给执行此文件的局部名空间
说明
首先要注意这里的globals和locals是参数,Python还有两个相像的内建函数分别是globals()
和locals()
,分别返回调用该函数处的全局变量字典和局部变量字典。
globals和locals参数可以分别传入两个字典,主要有两个作用,一是提供运行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]
两个参数 cls 和 inst 分别做了两件事:
- inst 负责生成 MRO 的 list
- 通过 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)]
示例中最后一个表达式涉及到的是参数解包,以后需要对其总结一下。